@lwc/babel-plugin-component 9.1.0 → 9.1.1-alpha.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.
@@ -1,6 +1,7 @@
1
1
  declare const LWC_PACKAGE_ALIAS = "lwc";
2
2
  declare const LWC_PACKAGE_EXPORTS: {
3
3
  BASE_COMPONENT: string;
4
+ MOSAIC_BASE_COMPONENT: string;
4
5
  API_DECORATOR: string;
5
6
  TRACK_DECORATOR: string;
6
7
  WIRE_DECORATOR: string;
package/dist/index.cjs CHANGED
@@ -8,8 +8,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
8
8
  var node_path = require('node:path');
9
9
  var helperModuleImports = require('@babel/helper-module-imports');
10
10
  var shared = require('@lwc/shared');
11
- var errors = require('@lwc/errors');
12
11
  var lineColumn = require('line-column');
12
+ var errors = require('@lwc/errors');
13
13
 
14
14
  /*
15
15
  * Copyright (c) 2023, salesforce.com, inc.
@@ -19,6 +19,7 @@ var lineColumn = require('line-column');
19
19
  */
20
20
  const LWC_PACKAGE_ALIAS = 'lwc';
21
21
  const LWC_PACKAGE_EXPORTS = {
22
+ MOSAIC_BASE_COMPONENT: 'Mosaic',
22
23
  API_DECORATOR: 'api',
23
24
  TRACK_DECORATOR: 'track',
24
25
  WIRE_DECORATOR: 'wire',
@@ -47,114 +48,6 @@ const ENABLE_PRIVATE_METHODS_KEY = 'enablePrivateMethods';
47
48
  const SYNTHETIC_ELEMENT_INTERNALS_KEY = 'enableSyntheticElementInternals';
48
49
  const COMPONENT_FEATURE_FLAG_KEY = 'componentFeatureFlag';
49
50
 
50
- /*
51
- * Copyright (c) 2023, salesforce.com, inc.
52
- * All rights reserved.
53
- * SPDX-License-Identifier: MIT
54
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
55
- */
56
- function getBaseName(classPath) {
57
- const ext = node_path.extname(classPath);
58
- return node_path.basename(classPath, ext);
59
- }
60
- function importDefaultTemplate(path, state) {
61
- const { filename } = state.file.opts;
62
- const componentName = getBaseName(filename);
63
- return helperModuleImports.addDefault(path, `./${componentName}.html`, {
64
- nameHint: TEMPLATE_KEY,
65
- });
66
- }
67
- function needsComponentRegistration(path) {
68
- return ((path.isIdentifier() && path.node.name !== 'undefined' && path.node.name !== 'null') ||
69
- path.isCallExpression() ||
70
- path.isClassDeclaration() ||
71
- path.isConditionalExpression());
72
- }
73
- function getComponentRegisteredName(t, state) {
74
- const { namespace, name } = state.opts;
75
- const componentName = shared.generateCustomElementTagName(namespace, name);
76
- return t.stringLiteral(componentName);
77
- }
78
- function component ({ types: t }) {
79
- function createRegisterComponent(declarationPath, state) {
80
- const registerComponentId = helperModuleImports.addNamed(declarationPath, REGISTER_COMPONENT_ID, LWC_PACKAGE_ALIAS);
81
- const templateIdentifier = importDefaultTemplate(declarationPath, state);
82
- // Optionally import feature flag module if provided via compiler options
83
- let componentFeatureFlagIdentifier;
84
- if (state.opts.componentFeatureFlagModulePath) {
85
- componentFeatureFlagIdentifier = helperModuleImports.addDefault(declarationPath, state.opts.componentFeatureFlagModulePath, {
86
- nameHint: COMPONENT_FEATURE_FLAG_KEY,
87
- });
88
- }
89
- const statementPath = declarationPath.getStatementParent();
90
- const componentRegisteredName = getComponentRegisteredName(t, state);
91
- let node = declarationPath.node;
92
- if (declarationPath.isClassDeclaration()) {
93
- const hasIdentifier = t.isIdentifier(node.id);
94
- if (hasIdentifier) {
95
- statementPath.insertBefore(node);
96
- node = node.id;
97
- }
98
- else {
99
- // if it does not have an id, we can treat it as a ClassExpression
100
- t.toExpression(node);
101
- }
102
- }
103
- const apiVersion = shared.getAPIVersionFromNumber(state.opts.apiVersion);
104
- // Example:
105
- // registerComponent(cmp, {
106
- // tmpl: template,
107
- // sel: 'x-foo',
108
- // apiVersion: '58'
109
- // })
110
- const properties = [
111
- t.objectProperty(t.identifier(TEMPLATE_KEY), templateIdentifier),
112
- t.objectProperty(t.identifier(COMPONENT_NAME_KEY), componentRegisteredName),
113
- // It's important that, at this point, we have an APIVersion rather than just a number.
114
- // The client needs to trust the server that it's providing an actual known API version
115
- t.objectProperty(t.identifier(API_VERSION_KEY), t.numericLiteral(apiVersion)),
116
- ];
117
- if (componentFeatureFlagIdentifier) {
118
- properties.push(t.objectProperty(t.identifier(COMPONENT_FEATURE_FLAG_KEY), t.objectExpression([
119
- t.objectProperty(t.identifier('value'), t.callExpression(t.identifier('Boolean'), [
120
- componentFeatureFlagIdentifier,
121
- ])),
122
- t.objectProperty(t.identifier('path'), t.stringLiteral(state.opts.componentFeatureFlagModulePath)),
123
- ])));
124
- }
125
- // Only include enableSyntheticElementInternals if set to true
126
- if (state.opts.enableSyntheticElementInternals === true) {
127
- properties.push(t.objectProperty(t.identifier(SYNTHETIC_ELEMENT_INTERNALS_KEY), t.booleanLiteral(true)));
128
- }
129
- if (state.opts.enablePrivateMethods === true) {
130
- properties.push(t.objectProperty(t.identifier(ENABLE_PRIVATE_METHODS_KEY), t.booleanLiteral(true)));
131
- }
132
- const registerComponentExpression = t.callExpression(registerComponentId, [
133
- node,
134
- t.objectExpression(properties),
135
- ]);
136
- // Example:
137
- // const __lwc_component_class_internal = registerComponent(cmp, ...);
138
- // This provides a way to access the component class for other lwc tools
139
- const classIdentifier = t.identifier(COMPONENT_CLASS_ID);
140
- declarationPath.parentPath.insertBefore(t.variableDeclaration('const', [
141
- t.variableDeclarator(classIdentifier, registerComponentExpression),
142
- ]));
143
- return classIdentifier;
144
- }
145
- return {
146
- ExportDefaultDeclaration(path, state) {
147
- const implicitResolution = !state.opts.isExplicitImport;
148
- if (implicitResolution) {
149
- const declaration = path.get('declaration');
150
- if (needsComponentRegistration(declaration)) {
151
- declaration.replaceWith(createRegisterComponent(declaration, state));
152
- }
153
- }
154
- },
155
- };
156
- }
157
-
158
51
  /*
159
52
  * Copyright (c) 2023, salesforce.com, inc.
160
53
  * All rights reserved.
@@ -289,6 +182,145 @@ function copyMethodMetadata(source, target) {
289
182
  if (source.override != null)
290
183
  target.override = source.override;
291
184
  }
185
+ /**
186
+ * Returns true if the given class path extends `Mosaic` imported from the `'lwc'` package.
187
+ * Used to apply Mosaic-specific compilation rules (no template, no @wire, etc.).
188
+ */
189
+ function isMosaic(classPath) {
190
+ const node = classPath.node;
191
+ const superClass = node.superClass;
192
+ if (!superClass || superClass.type !== 'Identifier') {
193
+ return false;
194
+ }
195
+ const superName = superClass.name;
196
+ const binding = classPath.scope.getBinding(superName);
197
+ if (!binding) {
198
+ return false;
199
+ }
200
+ const bindingPath = binding.path;
201
+ if (!bindingPath.isImportSpecifier()) {
202
+ return false;
203
+ }
204
+ const importDecl = bindingPath.parent;
205
+ if (importDecl.source.value !== LWC_PACKAGE_ALIAS) {
206
+ return false;
207
+ }
208
+ const importedName = bindingPath.node.imported
209
+ .name;
210
+ return importedName === LWC_PACKAGE_EXPORTS.MOSAIC_BASE_COMPONENT;
211
+ }
212
+
213
+ /*
214
+ * Copyright (c) 2023, salesforce.com, inc.
215
+ * All rights reserved.
216
+ * SPDX-License-Identifier: MIT
217
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
218
+ */
219
+ function getBaseName(classPath) {
220
+ const ext = node_path.extname(classPath);
221
+ return node_path.basename(classPath, ext);
222
+ }
223
+ function importDefaultTemplate(path, state) {
224
+ const { filename } = state.file.opts;
225
+ const componentName = getBaseName(filename);
226
+ return helperModuleImports.addDefault(path, `./${componentName}.html`, {
227
+ nameHint: TEMPLATE_KEY,
228
+ });
229
+ }
230
+ function needsComponentRegistration(path) {
231
+ if (path.isClassDeclaration() && isMosaic(path)) {
232
+ // Mosaics don't use an HTML template so are not registered as LWC components.
233
+ return false;
234
+ }
235
+ return ((path.isIdentifier() && path.node.name !== 'undefined' && path.node.name !== 'null') ||
236
+ path.isCallExpression() ||
237
+ path.isClassDeclaration() ||
238
+ path.isConditionalExpression());
239
+ }
240
+ function getComponentRegisteredName(t, state) {
241
+ const { namespace, name } = state.opts;
242
+ const componentName = shared.generateCustomElementTagName(namespace, name);
243
+ return t.stringLiteral(componentName);
244
+ }
245
+ function component ({ types: t }) {
246
+ function createRegisterComponent(declarationPath, state) {
247
+ const registerComponentId = helperModuleImports.addNamed(declarationPath, REGISTER_COMPONENT_ID, LWC_PACKAGE_ALIAS);
248
+ const templateIdentifier = importDefaultTemplate(declarationPath, state);
249
+ // Optionally import feature flag module if provided via compiler options
250
+ let componentFeatureFlagIdentifier;
251
+ if (state.opts.componentFeatureFlagModulePath) {
252
+ componentFeatureFlagIdentifier = helperModuleImports.addDefault(declarationPath, state.opts.componentFeatureFlagModulePath, {
253
+ nameHint: COMPONENT_FEATURE_FLAG_KEY,
254
+ });
255
+ }
256
+ const statementPath = declarationPath.getStatementParent();
257
+ const componentRegisteredName = getComponentRegisteredName(t, state);
258
+ let node = declarationPath.node;
259
+ if (declarationPath.isClassDeclaration()) {
260
+ const hasIdentifier = t.isIdentifier(node.id);
261
+ if (hasIdentifier) {
262
+ statementPath.insertBefore(node);
263
+ node = node.id;
264
+ }
265
+ else {
266
+ // if it does not have an id, we can treat it as a ClassExpression
267
+ t.toExpression(node);
268
+ }
269
+ }
270
+ const apiVersion = shared.getAPIVersionFromNumber(state.opts.apiVersion);
271
+ // Example:
272
+ // registerComponent(cmp, {
273
+ // tmpl: template,
274
+ // sel: 'x-foo',
275
+ // apiVersion: '58'
276
+ // })
277
+ const properties = [
278
+ t.objectProperty(t.identifier(TEMPLATE_KEY), templateIdentifier),
279
+ t.objectProperty(t.identifier(COMPONENT_NAME_KEY), componentRegisteredName),
280
+ // It's important that, at this point, we have an APIVersion rather than just a number.
281
+ // The client needs to trust the server that it's providing an actual known API version
282
+ t.objectProperty(t.identifier(API_VERSION_KEY), t.numericLiteral(apiVersion)),
283
+ ];
284
+ if (componentFeatureFlagIdentifier) {
285
+ properties.push(t.objectProperty(t.identifier(COMPONENT_FEATURE_FLAG_KEY), t.objectExpression([
286
+ t.objectProperty(t.identifier('value'), t.callExpression(t.identifier('Boolean'), [
287
+ componentFeatureFlagIdentifier,
288
+ ])),
289
+ t.objectProperty(t.identifier('path'), t.stringLiteral(state.opts.componentFeatureFlagModulePath)),
290
+ ])));
291
+ }
292
+ // Only include enableSyntheticElementInternals if set to true
293
+ if (state.opts.enableSyntheticElementInternals === true) {
294
+ properties.push(t.objectProperty(t.identifier(SYNTHETIC_ELEMENT_INTERNALS_KEY), t.booleanLiteral(true)));
295
+ }
296
+ if (state.opts.enablePrivateMethods === true) {
297
+ properties.push(t.objectProperty(t.identifier(ENABLE_PRIVATE_METHODS_KEY), t.booleanLiteral(true)));
298
+ }
299
+ const registerComponentExpression = t.callExpression(registerComponentId, [
300
+ node,
301
+ t.objectExpression(properties),
302
+ ]);
303
+ // Example:
304
+ // const __lwc_component_class_internal = registerComponent(cmp, ...);
305
+ // This provides a way to access the component class for other lwc tools
306
+ const classIdentifier = t.identifier(COMPONENT_CLASS_ID);
307
+ declarationPath.parentPath.insertBefore(t.variableDeclaration('const', [
308
+ t.variableDeclarator(classIdentifier, registerComponentExpression),
309
+ ]));
310
+ return classIdentifier;
311
+ }
312
+ return {
313
+ ExportDefaultDeclaration(path, state) {
314
+ const implicitResolution = !state.opts.isExplicitImport;
315
+ if (implicitResolution) {
316
+ const declaration = path.get('declaration');
317
+ if (needsComponentRegistration(declaration)) {
318
+ declaration.replaceWith(createRegisterComponent(declaration, state));
319
+ }
320
+ }
321
+ },
322
+ };
323
+ }
292
324
 
293
325
  /*
294
326
  * Copyright (c) 2023, salesforce.com, inc.
@@ -1137,6 +1169,19 @@ function decorators({ types: t }) {
1137
1169
  const decoratorMetas = decoratorPaths
1138
1170
  .map((path) => getDecoratorMetadata(path, state))
1139
1171
  .filter((meta) => meta !== null);
1172
+ // Mosaic classes may only use @api. @wire and @track are not allowed.
1173
+ if (isMosaic(path)) {
1174
+ const mosaicForbiddenDecorators = {
1175
+ [LWC_PACKAGE_EXPORTS.WIRE_DECORATOR]: errors.DecoratorErrors.MOSAIC_CANNOT_USE_WIRE,
1176
+ [LWC_PACKAGE_EXPORTS.TRACK_DECORATOR]: errors.DecoratorErrors.MOSAIC_CANNOT_USE_TRACK,
1177
+ };
1178
+ for (const meta of decoratorMetas) {
1179
+ const errorInfo = mosaicForbiddenDecorators[meta.name];
1180
+ if (errorInfo) {
1181
+ handleError(meta.path, { errorInfo }, state);
1182
+ }
1183
+ }
1184
+ }
1140
1185
  validate(decoratorMetas, state);
1141
1186
  const metaPropertyList = getMetadataObjectPropertyList(t, decoratorMetas, classBodyItems, state);
1142
1187
  if (metaPropertyList.length === 0) {
@@ -1508,5 +1553,5 @@ function LwcClassTransform(api) {
1508
1553
  exports.LwcPrivateMethodTransform = privateMethodTransform;
1509
1554
  exports.LwcReversePrivateMethodTransform = reversePrivateMethodTransform;
1510
1555
  exports.default = LwcClassTransform;
1511
- /** version: 9.1.0 */
1556
+ /** version: 9.1.1-alpha.0 */
1512
1557
  //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -4,8 +4,8 @@
4
4
  import { extname, basename } from 'node:path';
5
5
  import { addNamed, addDefault } from '@babel/helper-module-imports';
6
6
  import { getAPIVersionFromNumber, generateCustomElementTagName, DISALLOWED_PROP_SET, AMBIGUOUS_PROP_SET, isAPIFeatureEnabled, LWC_VERSION_COMMENT } from '@lwc/shared';
7
- import { generateCompilerDiagnostic, DiagnosticLevel, generateErrorMessage, DecoratorErrors, CompilerMetrics, LWCClassErrors } from '@lwc/errors';
8
7
  import lineColumn from 'line-column';
8
+ import { generateCompilerDiagnostic, DiagnosticLevel, generateErrorMessage, DecoratorErrors, CompilerMetrics, LWCClassErrors } from '@lwc/errors';
9
9
 
10
10
  /*
11
11
  * Copyright (c) 2023, salesforce.com, inc.
@@ -15,6 +15,7 @@ import lineColumn from 'line-column';
15
15
  */
16
16
  const LWC_PACKAGE_ALIAS = 'lwc';
17
17
  const LWC_PACKAGE_EXPORTS = {
18
+ MOSAIC_BASE_COMPONENT: 'Mosaic',
18
19
  API_DECORATOR: 'api',
19
20
  TRACK_DECORATOR: 'track',
20
21
  WIRE_DECORATOR: 'wire',
@@ -43,114 +44,6 @@ const ENABLE_PRIVATE_METHODS_KEY = 'enablePrivateMethods';
43
44
  const SYNTHETIC_ELEMENT_INTERNALS_KEY = 'enableSyntheticElementInternals';
44
45
  const COMPONENT_FEATURE_FLAG_KEY = 'componentFeatureFlag';
45
46
 
46
- /*
47
- * Copyright (c) 2023, salesforce.com, inc.
48
- * All rights reserved.
49
- * SPDX-License-Identifier: MIT
50
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
51
- */
52
- function getBaseName(classPath) {
53
- const ext = extname(classPath);
54
- return basename(classPath, ext);
55
- }
56
- function importDefaultTemplate(path, state) {
57
- const { filename } = state.file.opts;
58
- const componentName = getBaseName(filename);
59
- return addDefault(path, `./${componentName}.html`, {
60
- nameHint: TEMPLATE_KEY,
61
- });
62
- }
63
- function needsComponentRegistration(path) {
64
- return ((path.isIdentifier() && path.node.name !== 'undefined' && path.node.name !== 'null') ||
65
- path.isCallExpression() ||
66
- path.isClassDeclaration() ||
67
- path.isConditionalExpression());
68
- }
69
- function getComponentRegisteredName(t, state) {
70
- const { namespace, name } = state.opts;
71
- const componentName = generateCustomElementTagName(namespace, name);
72
- return t.stringLiteral(componentName);
73
- }
74
- function component ({ types: t }) {
75
- function createRegisterComponent(declarationPath, state) {
76
- const registerComponentId = addNamed(declarationPath, REGISTER_COMPONENT_ID, LWC_PACKAGE_ALIAS);
77
- const templateIdentifier = importDefaultTemplate(declarationPath, state);
78
- // Optionally import feature flag module if provided via compiler options
79
- let componentFeatureFlagIdentifier;
80
- if (state.opts.componentFeatureFlagModulePath) {
81
- componentFeatureFlagIdentifier = addDefault(declarationPath, state.opts.componentFeatureFlagModulePath, {
82
- nameHint: COMPONENT_FEATURE_FLAG_KEY,
83
- });
84
- }
85
- const statementPath = declarationPath.getStatementParent();
86
- const componentRegisteredName = getComponentRegisteredName(t, state);
87
- let node = declarationPath.node;
88
- if (declarationPath.isClassDeclaration()) {
89
- const hasIdentifier = t.isIdentifier(node.id);
90
- if (hasIdentifier) {
91
- statementPath.insertBefore(node);
92
- node = node.id;
93
- }
94
- else {
95
- // if it does not have an id, we can treat it as a ClassExpression
96
- t.toExpression(node);
97
- }
98
- }
99
- const apiVersion = getAPIVersionFromNumber(state.opts.apiVersion);
100
- // Example:
101
- // registerComponent(cmp, {
102
- // tmpl: template,
103
- // sel: 'x-foo',
104
- // apiVersion: '58'
105
- // })
106
- const properties = [
107
- t.objectProperty(t.identifier(TEMPLATE_KEY), templateIdentifier),
108
- t.objectProperty(t.identifier(COMPONENT_NAME_KEY), componentRegisteredName),
109
- // It's important that, at this point, we have an APIVersion rather than just a number.
110
- // The client needs to trust the server that it's providing an actual known API version
111
- t.objectProperty(t.identifier(API_VERSION_KEY), t.numericLiteral(apiVersion)),
112
- ];
113
- if (componentFeatureFlagIdentifier) {
114
- properties.push(t.objectProperty(t.identifier(COMPONENT_FEATURE_FLAG_KEY), t.objectExpression([
115
- t.objectProperty(t.identifier('value'), t.callExpression(t.identifier('Boolean'), [
116
- componentFeatureFlagIdentifier,
117
- ])),
118
- t.objectProperty(t.identifier('path'), t.stringLiteral(state.opts.componentFeatureFlagModulePath)),
119
- ])));
120
- }
121
- // Only include enableSyntheticElementInternals if set to true
122
- if (state.opts.enableSyntheticElementInternals === true) {
123
- properties.push(t.objectProperty(t.identifier(SYNTHETIC_ELEMENT_INTERNALS_KEY), t.booleanLiteral(true)));
124
- }
125
- if (state.opts.enablePrivateMethods === true) {
126
- properties.push(t.objectProperty(t.identifier(ENABLE_PRIVATE_METHODS_KEY), t.booleanLiteral(true)));
127
- }
128
- const registerComponentExpression = t.callExpression(registerComponentId, [
129
- node,
130
- t.objectExpression(properties),
131
- ]);
132
- // Example:
133
- // const __lwc_component_class_internal = registerComponent(cmp, ...);
134
- // This provides a way to access the component class for other lwc tools
135
- const classIdentifier = t.identifier(COMPONENT_CLASS_ID);
136
- declarationPath.parentPath.insertBefore(t.variableDeclaration('const', [
137
- t.variableDeclarator(classIdentifier, registerComponentExpression),
138
- ]));
139
- return classIdentifier;
140
- }
141
- return {
142
- ExportDefaultDeclaration(path, state) {
143
- const implicitResolution = !state.opts.isExplicitImport;
144
- if (implicitResolution) {
145
- const declaration = path.get('declaration');
146
- if (needsComponentRegistration(declaration)) {
147
- declaration.replaceWith(createRegisterComponent(declaration, state));
148
- }
149
- }
150
- },
151
- };
152
- }
153
-
154
47
  /*
155
48
  * Copyright (c) 2023, salesforce.com, inc.
156
49
  * All rights reserved.
@@ -285,6 +178,145 @@ function copyMethodMetadata(source, target) {
285
178
  if (source.override != null)
286
179
  target.override = source.override;
287
180
  }
181
+ /**
182
+ * Returns true if the given class path extends `Mosaic` imported from the `'lwc'` package.
183
+ * Used to apply Mosaic-specific compilation rules (no template, no @wire, etc.).
184
+ */
185
+ function isMosaic(classPath) {
186
+ const node = classPath.node;
187
+ const superClass = node.superClass;
188
+ if (!superClass || superClass.type !== 'Identifier') {
189
+ return false;
190
+ }
191
+ const superName = superClass.name;
192
+ const binding = classPath.scope.getBinding(superName);
193
+ if (!binding) {
194
+ return false;
195
+ }
196
+ const bindingPath = binding.path;
197
+ if (!bindingPath.isImportSpecifier()) {
198
+ return false;
199
+ }
200
+ const importDecl = bindingPath.parent;
201
+ if (importDecl.source.value !== LWC_PACKAGE_ALIAS) {
202
+ return false;
203
+ }
204
+ const importedName = bindingPath.node.imported
205
+ .name;
206
+ return importedName === LWC_PACKAGE_EXPORTS.MOSAIC_BASE_COMPONENT;
207
+ }
208
+
209
+ /*
210
+ * Copyright (c) 2023, salesforce.com, inc.
211
+ * All rights reserved.
212
+ * SPDX-License-Identifier: MIT
213
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
214
+ */
215
+ function getBaseName(classPath) {
216
+ const ext = extname(classPath);
217
+ return basename(classPath, ext);
218
+ }
219
+ function importDefaultTemplate(path, state) {
220
+ const { filename } = state.file.opts;
221
+ const componentName = getBaseName(filename);
222
+ return addDefault(path, `./${componentName}.html`, {
223
+ nameHint: TEMPLATE_KEY,
224
+ });
225
+ }
226
+ function needsComponentRegistration(path) {
227
+ if (path.isClassDeclaration() && isMosaic(path)) {
228
+ // Mosaics don't use an HTML template so are not registered as LWC components.
229
+ return false;
230
+ }
231
+ return ((path.isIdentifier() && path.node.name !== 'undefined' && path.node.name !== 'null') ||
232
+ path.isCallExpression() ||
233
+ path.isClassDeclaration() ||
234
+ path.isConditionalExpression());
235
+ }
236
+ function getComponentRegisteredName(t, state) {
237
+ const { namespace, name } = state.opts;
238
+ const componentName = generateCustomElementTagName(namespace, name);
239
+ return t.stringLiteral(componentName);
240
+ }
241
+ function component ({ types: t }) {
242
+ function createRegisterComponent(declarationPath, state) {
243
+ const registerComponentId = addNamed(declarationPath, REGISTER_COMPONENT_ID, LWC_PACKAGE_ALIAS);
244
+ const templateIdentifier = importDefaultTemplate(declarationPath, state);
245
+ // Optionally import feature flag module if provided via compiler options
246
+ let componentFeatureFlagIdentifier;
247
+ if (state.opts.componentFeatureFlagModulePath) {
248
+ componentFeatureFlagIdentifier = addDefault(declarationPath, state.opts.componentFeatureFlagModulePath, {
249
+ nameHint: COMPONENT_FEATURE_FLAG_KEY,
250
+ });
251
+ }
252
+ const statementPath = declarationPath.getStatementParent();
253
+ const componentRegisteredName = getComponentRegisteredName(t, state);
254
+ let node = declarationPath.node;
255
+ if (declarationPath.isClassDeclaration()) {
256
+ const hasIdentifier = t.isIdentifier(node.id);
257
+ if (hasIdentifier) {
258
+ statementPath.insertBefore(node);
259
+ node = node.id;
260
+ }
261
+ else {
262
+ // if it does not have an id, we can treat it as a ClassExpression
263
+ t.toExpression(node);
264
+ }
265
+ }
266
+ const apiVersion = getAPIVersionFromNumber(state.opts.apiVersion);
267
+ // Example:
268
+ // registerComponent(cmp, {
269
+ // tmpl: template,
270
+ // sel: 'x-foo',
271
+ // apiVersion: '58'
272
+ // })
273
+ const properties = [
274
+ t.objectProperty(t.identifier(TEMPLATE_KEY), templateIdentifier),
275
+ t.objectProperty(t.identifier(COMPONENT_NAME_KEY), componentRegisteredName),
276
+ // It's important that, at this point, we have an APIVersion rather than just a number.
277
+ // The client needs to trust the server that it's providing an actual known API version
278
+ t.objectProperty(t.identifier(API_VERSION_KEY), t.numericLiteral(apiVersion)),
279
+ ];
280
+ if (componentFeatureFlagIdentifier) {
281
+ properties.push(t.objectProperty(t.identifier(COMPONENT_FEATURE_FLAG_KEY), t.objectExpression([
282
+ t.objectProperty(t.identifier('value'), t.callExpression(t.identifier('Boolean'), [
283
+ componentFeatureFlagIdentifier,
284
+ ])),
285
+ t.objectProperty(t.identifier('path'), t.stringLiteral(state.opts.componentFeatureFlagModulePath)),
286
+ ])));
287
+ }
288
+ // Only include enableSyntheticElementInternals if set to true
289
+ if (state.opts.enableSyntheticElementInternals === true) {
290
+ properties.push(t.objectProperty(t.identifier(SYNTHETIC_ELEMENT_INTERNALS_KEY), t.booleanLiteral(true)));
291
+ }
292
+ if (state.opts.enablePrivateMethods === true) {
293
+ properties.push(t.objectProperty(t.identifier(ENABLE_PRIVATE_METHODS_KEY), t.booleanLiteral(true)));
294
+ }
295
+ const registerComponentExpression = t.callExpression(registerComponentId, [
296
+ node,
297
+ t.objectExpression(properties),
298
+ ]);
299
+ // Example:
300
+ // const __lwc_component_class_internal = registerComponent(cmp, ...);
301
+ // This provides a way to access the component class for other lwc tools
302
+ const classIdentifier = t.identifier(COMPONENT_CLASS_ID);
303
+ declarationPath.parentPath.insertBefore(t.variableDeclaration('const', [
304
+ t.variableDeclarator(classIdentifier, registerComponentExpression),
305
+ ]));
306
+ return classIdentifier;
307
+ }
308
+ return {
309
+ ExportDefaultDeclaration(path, state) {
310
+ const implicitResolution = !state.opts.isExplicitImport;
311
+ if (implicitResolution) {
312
+ const declaration = path.get('declaration');
313
+ if (needsComponentRegistration(declaration)) {
314
+ declaration.replaceWith(createRegisterComponent(declaration, state));
315
+ }
316
+ }
317
+ },
318
+ };
319
+ }
288
320
 
289
321
  /*
290
322
  * Copyright (c) 2023, salesforce.com, inc.
@@ -1133,6 +1165,19 @@ function decorators({ types: t }) {
1133
1165
  const decoratorMetas = decoratorPaths
1134
1166
  .map((path) => getDecoratorMetadata(path, state))
1135
1167
  .filter((meta) => meta !== null);
1168
+ // Mosaic classes may only use @api. @wire and @track are not allowed.
1169
+ if (isMosaic(path)) {
1170
+ const mosaicForbiddenDecorators = {
1171
+ [LWC_PACKAGE_EXPORTS.WIRE_DECORATOR]: DecoratorErrors.MOSAIC_CANNOT_USE_WIRE,
1172
+ [LWC_PACKAGE_EXPORTS.TRACK_DECORATOR]: DecoratorErrors.MOSAIC_CANNOT_USE_TRACK,
1173
+ };
1174
+ for (const meta of decoratorMetas) {
1175
+ const errorInfo = mosaicForbiddenDecorators[meta.name];
1176
+ if (errorInfo) {
1177
+ handleError(meta.path, { errorInfo }, state);
1178
+ }
1179
+ }
1180
+ }
1136
1181
  validate(decoratorMetas, state);
1137
1182
  const metaPropertyList = getMetadataObjectPropertyList(t, decoratorMetas, classBodyItems, state);
1138
1183
  if (metaPropertyList.length === 0) {
@@ -1502,5 +1547,5 @@ function LwcClassTransform(api) {
1502
1547
  }
1503
1548
 
1504
1549
  export { privateMethodTransform as LwcPrivateMethodTransform, reversePrivateMethodTransform as LwcReversePrivateMethodTransform, LwcClassTransform as default };
1505
- /** version: 9.1.0 */
1550
+ /** version: 9.1.1-alpha.0 */
1506
1551
  //# sourceMappingURL=index.js.map
package/dist/utils.d.ts CHANGED
@@ -28,5 +28,10 @@ declare function isErrorRecoveryMode(state: LwcBabelPluginPass): boolean;
28
28
  * private-method transforms use this to maintain round-trip parity.
29
29
  */
30
30
  declare function copyMethodMetadata(source: types.ClassMethod | types.ClassPrivateMethod, target: types.ClassMethod | types.ClassPrivateMethod): void;
31
- export { isClassMethod, isGetterClassMethod, isSetterClassMethod, getEngineImportSpecifiers, handleError, incrementMetricCounter, isErrorRecoveryMode, copyMethodMetadata, };
31
+ /**
32
+ * Returns true if the given class path extends `Mosaic` imported from the `'lwc'` package.
33
+ * Used to apply Mosaic-specific compilation rules (no template, no @wire, etc.).
34
+ */
35
+ declare function isMosaic(classPath: NodePath): boolean;
36
+ export { isClassMethod, isGetterClassMethod, isSetterClassMethod, getEngineImportSpecifiers, handleError, incrementMetricCounter, isErrorRecoveryMode, copyMethodMetadata, isMosaic, };
32
37
  //# sourceMappingURL=utils.d.ts.map
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten."
5
5
  ],
6
6
  "name": "@lwc/babel-plugin-component",
7
- "version": "9.1.0",
7
+ "version": "9.1.1-alpha.0",
8
8
  "description": "Babel plugin to transform a LWC module",
9
9
  "keywords": [
10
10
  "lwc"
@@ -52,8 +52,8 @@
52
52
  },
53
53
  "dependencies": {
54
54
  "@babel/helper-module-imports": "7.28.6",
55
- "@lwc/errors": "9.1.0",
56
- "@lwc/shared": "9.1.0",
55
+ "@lwc/errors": "9.1.1-alpha.0",
56
+ "@lwc/shared": "9.1.1-alpha.0",
57
57
  "line-column": "~1.0.2"
58
58
  },
59
59
  "devDependencies": {