@lwc/ssr-compiler 8.12.0 → 8.12.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/compile-js/index.d.ts +2 -1
- package/dist/compile-js/types.d.ts +4 -0
- package/dist/compile-template/shared.d.ts +6 -0
- package/dist/compile-template/types.d.ts +1 -0
- package/dist/imports.d.ts +8 -0
- package/dist/index.cjs.js +196 -101
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +197 -102
- package/dist/index.js.map +1 -1
- package/dist/shared.d.ts +5 -1
- package/package.json +6 -5
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
import type { ComponentTransformOptions } from '../shared';
|
|
1
2
|
import type { CompilationMode } from '@lwc/shared';
|
|
2
|
-
export default function compileJS(src: string, filename: string, tagName: string, compilationMode: CompilationMode): {
|
|
3
|
+
export default function compileJS(src: string, filename: string, tagName: string, options: ComponentTransformOptions, compilationMode: CompilationMode): {
|
|
3
4
|
code: string;
|
|
4
5
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ImportManager } from '../imports';
|
|
2
|
+
import type { ComponentTransformOptions } from '../shared';
|
|
1
3
|
import type { traverse } from 'estree-toolkit';
|
|
2
4
|
import type { Identifier, MemberExpression, MethodDefinition, Node, ObjectExpression, PropertyDefinition } from 'estree';
|
|
3
5
|
export type Visitors = Parameters<typeof traverse<Node, ComponentMetaState>>[1];
|
|
@@ -22,4 +24,6 @@ export interface ComponentMetaState {
|
|
|
22
24
|
publicFields: Array<string>;
|
|
23
25
|
privateFields: Array<string>;
|
|
24
26
|
wireAdapters: WireAdapter[];
|
|
27
|
+
experimentalDynamicComponent: ComponentTransformOptions['experimentalDynamicComponent'];
|
|
28
|
+
importManager: ImportManager;
|
|
25
29
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { TransformerContext } from './types';
|
|
2
2
|
import type { Attribute as IrAttribute, Node as IrNode, Property as IrProperty } from '@lwc/template-compiler';
|
|
3
3
|
import type { Expression as EsExpression, ObjectExpression as EsObjectExpression, Statement as EsStatement } from 'estree';
|
|
4
|
+
import type { ComplexExpression as IrComplexExpression, Expression as IrExpression, Literal as IrLiteral } from '@lwc/template-compiler';
|
|
4
5
|
export declare function optimizeAdjacentYieldStmts(statements: EsStatement[]): EsStatement[];
|
|
5
6
|
export declare function bAttributeValue(node: IrNode, attrName: string): EsExpression;
|
|
6
7
|
/**
|
|
@@ -14,3 +15,8 @@ export declare function bAttributeValue(node: IrNode, attrName: string): EsExpre
|
|
|
14
15
|
export declare function getScopedExpression(expression: EsExpression, cxt: TransformerContext): EsExpression;
|
|
15
16
|
export declare function normalizeClassAttributeValue(value: string): string;
|
|
16
17
|
export declare function getChildAttrsOrProps(attrs: (IrAttribute | IrProperty)[], cxt: TransformerContext): EsObjectExpression;
|
|
18
|
+
/**
|
|
19
|
+
* Determine if the provided node is of type Literal
|
|
20
|
+
* @param node
|
|
21
|
+
*/
|
|
22
|
+
export declare function isLiteral(node: IrLiteral | IrExpression | IrComplexExpression): node is IrLiteral;
|
|
@@ -8,6 +8,7 @@ export interface TransformerContext {
|
|
|
8
8
|
templateOptions: TemplateOpts;
|
|
9
9
|
prevSibling?: IrNode;
|
|
10
10
|
nextSibling?: IrNode;
|
|
11
|
+
isSlotted?: boolean;
|
|
11
12
|
import: (imports: string | string[] | Record<string, string | undefined>, source?: string) => void;
|
|
12
13
|
}
|
|
13
14
|
export interface TemplateOpts {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ImportDeclaration } from 'estree';
|
|
2
|
+
export declare class ImportManager {
|
|
3
|
+
#private;
|
|
4
|
+
/** Add an import to a collection of imports, probably for adding to the AST later. */
|
|
5
|
+
add(imports: string | string[] | Record<string, string | undefined>, source?: string): void;
|
|
6
|
+
/** Get the collection of imports for adding to the AST, probably soon! */
|
|
7
|
+
getImportDeclarations(): ImportDeclaration[];
|
|
8
|
+
}
|
package/dist/index.cjs.js
CHANGED
|
@@ -165,6 +165,116 @@ function transmogrify(compiledComponentAst, mode = 'sync') {
|
|
|
165
165
|
return immer.produce(compiledComponentAst, (astDraft) => estreeToolkit.traverse(astDraft, visitors$2, state));
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
/******************************************************************************
|
|
169
|
+
Copyright (c) Microsoft Corporation.
|
|
170
|
+
|
|
171
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
172
|
+
purpose with or without fee is hereby granted.
|
|
173
|
+
|
|
174
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
175
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
176
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
177
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
178
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
179
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
180
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
181
|
+
***************************************************************************** */
|
|
182
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
function __classPrivateFieldGet(receiver, state, kind, f) {
|
|
186
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
187
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
188
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
192
|
+
var e = new Error(message);
|
|
193
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
/*
|
|
197
|
+
* Copyright (c) 2024, salesforce.com, inc.
|
|
198
|
+
* All rights reserved.
|
|
199
|
+
* SPDX-License-Identifier: MIT
|
|
200
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
201
|
+
*/
|
|
202
|
+
/**
|
|
203
|
+
* Creates an import statement, e.g. `import { foo, bar as $bar$ } from "pkg"`
|
|
204
|
+
* @param imports names to be imported; values can be a string (plain import) or object (aliased)
|
|
205
|
+
* @param source source location to import from; defaults to @lwc/ssr-runtime
|
|
206
|
+
*/
|
|
207
|
+
const bImportDeclaration = (imports, source = '@lwc/ssr-runtime') => {
|
|
208
|
+
let parsed;
|
|
209
|
+
if (typeof imports === 'string') {
|
|
210
|
+
parsed = [[imports, undefined]];
|
|
211
|
+
}
|
|
212
|
+
else if (Array.isArray(imports)) {
|
|
213
|
+
parsed = imports.map((imp) => [imp, undefined]);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
parsed = Object.entries(imports);
|
|
217
|
+
}
|
|
218
|
+
const specifiers = parsed.map(([imported, local]) => {
|
|
219
|
+
if (imported === 'default') {
|
|
220
|
+
return estreeToolkit.builders.importDefaultSpecifier(estreeToolkit.builders.identifier(local));
|
|
221
|
+
}
|
|
222
|
+
else if (imported === '*') {
|
|
223
|
+
return estreeToolkit.builders.importNamespaceSpecifier(estreeToolkit.builders.identifier(local));
|
|
224
|
+
}
|
|
225
|
+
else if (local) {
|
|
226
|
+
return estreeToolkit.builders.importSpecifier(estreeToolkit.builders.identifier(imported), estreeToolkit.builders.identifier(local));
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
return estreeToolkit.builders.importSpecifier(estreeToolkit.builders.identifier(imported));
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
return estreeToolkit.builders.importDeclaration(specifiers, estreeToolkit.builders.literal(source));
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
/*
|
|
236
|
+
* Copyright (c) 2024, Salesforce, Inc.
|
|
237
|
+
* All rights reserved.
|
|
238
|
+
* SPDX-License-Identifier: MIT
|
|
239
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
240
|
+
*/
|
|
241
|
+
var _ImportManager_map;
|
|
242
|
+
class ImportManager {
|
|
243
|
+
constructor() {
|
|
244
|
+
_ImportManager_map.set(this, new Map());
|
|
245
|
+
}
|
|
246
|
+
/** Add an import to a collection of imports, probably for adding to the AST later. */
|
|
247
|
+
add(imports, source = '@lwc/ssr-runtime') {
|
|
248
|
+
let specifiers;
|
|
249
|
+
if (typeof imports === 'string') {
|
|
250
|
+
specifiers = [[imports, undefined]];
|
|
251
|
+
}
|
|
252
|
+
else if (Array.isArray(imports)) {
|
|
253
|
+
specifiers = imports.map((name) => [name, undefined]);
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
specifiers = Object.entries(imports);
|
|
257
|
+
}
|
|
258
|
+
let specifierMap = __classPrivateFieldGet(this, _ImportManager_map, "f").get(source);
|
|
259
|
+
if (specifierMap) {
|
|
260
|
+
for (const [imported, local] of specifiers) {
|
|
261
|
+
specifierMap.set(imported, local);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
specifierMap = new Map(specifiers);
|
|
266
|
+
__classPrivateFieldGet(this, _ImportManager_map, "f").set(source, specifierMap);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/** Get the collection of imports for adding to the AST, probably soon! */
|
|
270
|
+
getImportDeclarations() {
|
|
271
|
+
return Array.from(__classPrivateFieldGet(this, _ImportManager_map, "f"), ([source, specifierMap]) => {
|
|
272
|
+
return bImportDeclaration(Object.fromEntries(specifierMap), source);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
_ImportManager_map = new WeakMap();
|
|
277
|
+
|
|
168
278
|
/*
|
|
169
279
|
* Copyright (c) 2024, salesforce.com, inc.
|
|
170
280
|
* All rights reserved.
|
|
@@ -440,45 +550,6 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
440
550
|
}
|
|
441
551
|
}
|
|
442
552
|
|
|
443
|
-
/*
|
|
444
|
-
* Copyright (c) 2024, salesforce.com, inc.
|
|
445
|
-
* All rights reserved.
|
|
446
|
-
* SPDX-License-Identifier: MIT
|
|
447
|
-
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
448
|
-
*/
|
|
449
|
-
/**
|
|
450
|
-
* Creates an import statement, e.g. `import { foo, bar as $bar$ } from "pkg"`
|
|
451
|
-
* @param imports names to be imported; values can be a string (plain import) or object (aliased)
|
|
452
|
-
* @param source source location to import from; defaults to @lwc/ssr-runtime
|
|
453
|
-
*/
|
|
454
|
-
const bImportDeclaration = (imports, source = '@lwc/ssr-runtime') => {
|
|
455
|
-
let parsed;
|
|
456
|
-
if (typeof imports === 'string') {
|
|
457
|
-
parsed = [[imports, undefined]];
|
|
458
|
-
}
|
|
459
|
-
else if (Array.isArray(imports)) {
|
|
460
|
-
parsed = imports.map((imp) => [imp, undefined]);
|
|
461
|
-
}
|
|
462
|
-
else {
|
|
463
|
-
parsed = Object.entries(imports);
|
|
464
|
-
}
|
|
465
|
-
const specifiers = parsed.map(([imported, local]) => {
|
|
466
|
-
if (imported === 'default') {
|
|
467
|
-
return estreeToolkit.builders.importDefaultSpecifier(estreeToolkit.builders.identifier(local));
|
|
468
|
-
}
|
|
469
|
-
else if (imported === '*') {
|
|
470
|
-
return estreeToolkit.builders.importNamespaceSpecifier(estreeToolkit.builders.identifier(local));
|
|
471
|
-
}
|
|
472
|
-
else if (local) {
|
|
473
|
-
return estreeToolkit.builders.importSpecifier(estreeToolkit.builders.identifier(imported), estreeToolkit.builders.identifier(local));
|
|
474
|
-
}
|
|
475
|
-
else {
|
|
476
|
-
return estreeToolkit.builders.importSpecifier(estreeToolkit.builders.identifier(imported));
|
|
477
|
-
}
|
|
478
|
-
});
|
|
479
|
-
return estreeToolkit.builders.importDeclaration(specifiers, estreeToolkit.builders.literal(source));
|
|
480
|
-
};
|
|
481
|
-
|
|
482
553
|
/*
|
|
483
554
|
* Copyright (c) 2024, salesforce.com, inc.
|
|
484
555
|
* All rights reserved.
|
|
@@ -496,19 +567,23 @@ function bMemberExpressionChain(props) {
|
|
|
496
567
|
function getWireParams(node) {
|
|
497
568
|
const { decorators } = node;
|
|
498
569
|
if (decorators.length > 1) {
|
|
570
|
+
// TODO [#5032]: Harmonize errors thrown in `@lwc/ssr-compiler`
|
|
499
571
|
throw new Error('todo - multiple decorators at once');
|
|
500
572
|
}
|
|
501
573
|
// validate the parameters
|
|
502
574
|
const wireDecorator = decorators[0].expression;
|
|
503
575
|
if (!estreeToolkit.is.callExpression(wireDecorator)) {
|
|
576
|
+
// TODO [#5032]: Harmonize errors thrown in `@lwc/ssr-compiler`
|
|
504
577
|
throw new Error('todo - invalid usage');
|
|
505
578
|
}
|
|
506
579
|
const args = wireDecorator.arguments;
|
|
507
580
|
if (args.length === 0 || args.length > 2) {
|
|
581
|
+
// TODO [#5032]: Harmonize errors thrown in `@lwc/ssr-compiler`
|
|
508
582
|
throw new Error('todo - wrong number of args');
|
|
509
583
|
}
|
|
510
584
|
const [id, config] = args;
|
|
511
585
|
if (estreeToolkit.is.spreadElement(id) || estreeToolkit.is.spreadElement(config)) {
|
|
586
|
+
// TODO [#5032]: Harmonize errors thrown in `@lwc/ssr-compiler`
|
|
512
587
|
throw new Error('todo - spread in params');
|
|
513
588
|
}
|
|
514
589
|
return [id, config];
|
|
@@ -518,14 +593,17 @@ function validateWireId(id, path) {
|
|
|
518
593
|
let wireAdapterVar;
|
|
519
594
|
if (estreeToolkit.is.memberExpression(id)) {
|
|
520
595
|
if (id.computed) {
|
|
596
|
+
// TODO [#5032]: Harmonize errors thrown in `@lwc/ssr-compiler`
|
|
521
597
|
throw new Error('todo - FUNCTION_IDENTIFIER_CANNOT_HAVE_COMPUTED_PROPS');
|
|
522
598
|
}
|
|
523
599
|
if (!estreeToolkit.is.identifier(id.object)) {
|
|
600
|
+
// TODO [#5032]: Harmonize errors thrown in `@lwc/ssr-compiler`
|
|
524
601
|
throw new Error('todo - FUNCTION_IDENTIFIER_CANNOT_HAVE_NESTED_MEMBER_EXRESSIONS');
|
|
525
602
|
}
|
|
526
603
|
wireAdapterVar = id.object.name;
|
|
527
604
|
}
|
|
528
605
|
else if (!estreeToolkit.is.identifier(id)) {
|
|
606
|
+
// TODO [#5032]: Harmonize errors thrown in `@lwc/ssr-compiler`
|
|
529
607
|
throw new Error('todo - invalid adapter name');
|
|
530
608
|
}
|
|
531
609
|
else {
|
|
@@ -533,11 +611,13 @@ function validateWireId(id, path) {
|
|
|
533
611
|
}
|
|
534
612
|
// This is not the exact same validation done in @lwc/babel-plugin-component but it accomplishes the same thing
|
|
535
613
|
if (path.scope?.getBinding(wireAdapterVar)?.kind !== 'module') {
|
|
614
|
+
// TODO [#5032]: Harmonize errors thrown in `@lwc/ssr-compiler`
|
|
536
615
|
throw new Error('todo - WIRE_ADAPTER_SHOULD_BE_IMPORTED');
|
|
537
616
|
}
|
|
538
617
|
}
|
|
539
618
|
function validateWireConfig(config, path) {
|
|
540
619
|
if (!estreeToolkit.is.objectExpression(config)) {
|
|
620
|
+
// TODO [#5032]: Harmonize errors thrown in `@lwc/ssr-compiler`
|
|
541
621
|
throw new Error('todo - CONFIG_OBJECT_SHOULD_BE_SECOND_PARAMETER');
|
|
542
622
|
}
|
|
543
623
|
for (const property of config.properties) {
|
|
@@ -560,6 +640,7 @@ function validateWireConfig(config, path) {
|
|
|
560
640
|
if (estreeToolkit.is.templateLiteral(key)) {
|
|
561
641
|
// A template literal is not guaranteed to always result in the same value
|
|
562
642
|
// (e.g. `${Math.random()}`), so we disallow them entirely.
|
|
643
|
+
// TODO [#5032]: Harmonize errors thrown in `@lwc/ssr-compiler`
|
|
563
644
|
throw new Error('todo - COMPUTED_PROPERTY_CANNOT_BE_TEMPLATE_LITERAL');
|
|
564
645
|
}
|
|
565
646
|
else if (!('regex' in key)) {
|
|
@@ -567,6 +648,7 @@ function validateWireConfig(config, path) {
|
|
|
567
648
|
continue;
|
|
568
649
|
}
|
|
569
650
|
}
|
|
651
|
+
// TODO [#5032]: Harmonize errors thrown in `@lwc/ssr-compiler`
|
|
570
652
|
throw new Error('todo - COMPUTED_PROPERTY_MUST_BE_CONSTANT_OR_LITERAL');
|
|
571
653
|
}
|
|
572
654
|
}
|
|
@@ -788,8 +870,28 @@ const visitors = {
|
|
|
788
870
|
catalogAndReplaceStyleImports(path, state);
|
|
789
871
|
removeDecoratorImport(path);
|
|
790
872
|
},
|
|
791
|
-
ImportExpression(path) {
|
|
792
|
-
|
|
873
|
+
ImportExpression(path, state) {
|
|
874
|
+
const { experimentalDynamicComponent, importManager } = state;
|
|
875
|
+
if (!experimentalDynamicComponent) {
|
|
876
|
+
// if no `experimentalDynamicComponent` config, then leave dynamic `import()`s as-is
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
if (experimentalDynamicComponent.strictSpecifier) {
|
|
880
|
+
if (!estreeToolkit.is.literal(path.node?.source) || typeof path.node.source.value !== 'string') {
|
|
881
|
+
// TODO [#5032]: Harmonize errors thrown in `@lwc/ssr-compiler`
|
|
882
|
+
throw new Error('todo - LWCClassErrors.INVALID_DYNAMIC_IMPORT_SOURCE_STRICT');
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
const loader = experimentalDynamicComponent.loader;
|
|
886
|
+
if (!loader) {
|
|
887
|
+
// if no `loader` defined, then leave dynamic `import()`s as-is
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
const source = path.node.source;
|
|
891
|
+
// 1. insert `import { load as __load } from '${loader}'` at top of program
|
|
892
|
+
importManager.add({ load: '__load' }, loader);
|
|
893
|
+
// 2. replace this import with `__load(${source})`
|
|
894
|
+
path.replaceWith(estreeToolkit.builders.callExpression(estreeToolkit.builders.identifier('__load'), [structuredClone(source)]));
|
|
793
895
|
},
|
|
794
896
|
ClassDeclaration(path, state) {
|
|
795
897
|
const { node } = path;
|
|
@@ -902,8 +1004,17 @@ const visitors = {
|
|
|
902
1004
|
path.parentPath.node.arguments = [estreeToolkit.builders.identifier('propsAvailableAtConstruction')];
|
|
903
1005
|
}
|
|
904
1006
|
},
|
|
1007
|
+
Program: {
|
|
1008
|
+
leave(path, state) {
|
|
1009
|
+
// After parsing the whole tree, insert needed imports
|
|
1010
|
+
const importDeclarations = state.importManager.getImportDeclarations();
|
|
1011
|
+
if (importDeclarations.length > 0) {
|
|
1012
|
+
path.node?.body.unshift(...importDeclarations);
|
|
1013
|
+
}
|
|
1014
|
+
},
|
|
1015
|
+
},
|
|
905
1016
|
};
|
|
906
|
-
function compileJS(src, filename, tagName, compilationMode) {
|
|
1017
|
+
function compileJS(src, filename, tagName, options, compilationMode) {
|
|
907
1018
|
let ast = meriyah.parseModule(src, {
|
|
908
1019
|
module: true,
|
|
909
1020
|
next: true,
|
|
@@ -924,6 +1035,8 @@ function compileJS(src, filename, tagName, compilationMode) {
|
|
|
924
1035
|
publicFields: [],
|
|
925
1036
|
privateFields: [],
|
|
926
1037
|
wireAdapters: [],
|
|
1038
|
+
experimentalDynamicComponent: options.experimentalDynamicComponent,
|
|
1039
|
+
importManager: new ImportManager(),
|
|
927
1040
|
};
|
|
928
1041
|
estreeToolkit.traverse(ast, visitors, state);
|
|
929
1042
|
if (!state.isLWC) {
|
|
@@ -1138,6 +1251,13 @@ function getChildAttrsOrProps(attrs, cxt) {
|
|
|
1138
1251
|
.filter(Boolean);
|
|
1139
1252
|
return estreeToolkit.builders.objectExpression(objectAttrsOrProps);
|
|
1140
1253
|
}
|
|
1254
|
+
/**
|
|
1255
|
+
* Determine if the provided node is of type Literal
|
|
1256
|
+
* @param node
|
|
1257
|
+
*/
|
|
1258
|
+
function isLiteral(node) {
|
|
1259
|
+
return node.type === 'Literal';
|
|
1260
|
+
}
|
|
1141
1261
|
|
|
1142
1262
|
/*
|
|
1143
1263
|
* Copyright (c) 2024, Salesforce, Inc.
|
|
@@ -1327,6 +1447,8 @@ function getLightSlottedContent(rootNodes, cxt) {
|
|
|
1327
1447
|
return results;
|
|
1328
1448
|
}
|
|
1329
1449
|
function getSlottedContent(node, cxt) {
|
|
1450
|
+
const { isSlotted } = cxt;
|
|
1451
|
+
cxt.isSlotted = true;
|
|
1330
1452
|
// Anything inside the slotted content is a normal slotted content except for `<template lwc:slot-data>` which is a scoped slot.
|
|
1331
1453
|
const slottableChildren = node.children.filter((child) => child.type !== 'ScopedSlotFragment');
|
|
1332
1454
|
const scopedSlottableChildren = node.children.filter((child) => child.type === 'ScopedSlotFragment');
|
|
@@ -1336,13 +1458,17 @@ function getSlottedContent(node, cxt) {
|
|
|
1336
1458
|
const boundVariableName = child.slotData.value.name;
|
|
1337
1459
|
const boundVariable = estreeToolkit.builders.identifier(boundVariableName);
|
|
1338
1460
|
cxt.pushLocalVars([boundVariableName]);
|
|
1461
|
+
const slotName = isLiteral(child.slotName)
|
|
1462
|
+
? estreeToolkit.builders.literal(child.slotName.value)
|
|
1463
|
+
: expressionIrToEs(child.slotName, cxt);
|
|
1339
1464
|
// TODO [#4768]: what if the bound variable is `generateMarkup` or some framework-specific identifier?
|
|
1340
|
-
const addLightContentExpr = estreeToolkit.builders.expressionStatement(bAddLightContent(
|
|
1465
|
+
const addLightContentExpr = estreeToolkit.builders.expressionStatement(bAddLightContent(slotName, boundVariable, irChildrenToEs(child.children, cxt)));
|
|
1341
1466
|
cxt.popLocalVars();
|
|
1342
1467
|
return addLightContentExpr;
|
|
1343
1468
|
});
|
|
1344
1469
|
const hasShadowSlottedContent = estreeToolkit.builders.literal(shadowSlotContent.length > 0);
|
|
1345
1470
|
const hasLightSlottedContent = estreeToolkit.builders.literal(lightSlotContent.length > 0 || scopedSlotContent.length > 0);
|
|
1471
|
+
cxt.isSlotted = isSlotted;
|
|
1346
1472
|
return bGenerateSlottedContent(hasShadowSlottedContent, shadowSlotContent, hasLightSlottedContent, lightSlotContent, scopedSlotContent);
|
|
1347
1473
|
}
|
|
1348
1474
|
|
|
@@ -1615,9 +1741,6 @@ const Element = function Element(node, cxt) {
|
|
|
1615
1741
|
}
|
|
1616
1742
|
return result;
|
|
1617
1743
|
});
|
|
1618
|
-
if (shared.isVoidElement(node.name, shared.HTML_NAMESPACE)) {
|
|
1619
|
-
return [bYield(estreeToolkit.builders.literal(`<${node.name}`)), ...yieldAttrsAndProps, bYield(estreeToolkit.builders.literal(`>`))];
|
|
1620
|
-
}
|
|
1621
1744
|
let childContent;
|
|
1622
1745
|
// An element can have children or lwc:inner-html, but not both
|
|
1623
1746
|
// If it has both, the template compiler will throw an error before reaching here
|
|
@@ -1633,14 +1756,15 @@ const Element = function Element(node, cxt) {
|
|
|
1633
1756
|
else {
|
|
1634
1757
|
childContent = [];
|
|
1635
1758
|
}
|
|
1759
|
+
const isForeignSelfClosingElement = node.namespace !== shared.HTML_NAMESPACE && childContent.length === 0;
|
|
1760
|
+
const isSelfClosingElement = shared.isVoidElement(node.name, shared.HTML_NAMESPACE) || isForeignSelfClosingElement;
|
|
1636
1761
|
return [
|
|
1637
1762
|
bYield(estreeToolkit.builders.literal(`<${node.name}`)),
|
|
1638
1763
|
// If we haven't already prefixed the scope token to an existing class, add an explicit class here
|
|
1639
1764
|
...(hasClassAttribute ? [] : [bConditionallyYieldScopeTokenClass()]),
|
|
1640
1765
|
...yieldAttrsAndProps,
|
|
1641
|
-
bYield(estreeToolkit.builders.literal(`>`)),
|
|
1642
|
-
...childContent,
|
|
1643
|
-
bYield(estreeToolkit.builders.literal(`</${node.name}>`)),
|
|
1766
|
+
bYield(estreeToolkit.builders.literal(isForeignSelfClosingElement ? `/>` : `>`)),
|
|
1767
|
+
...(isSelfClosingElement ? [] : [...childContent, bYield(estreeToolkit.builders.literal(`</${node.name}>`))]),
|
|
1644
1768
|
].filter(Boolean);
|
|
1645
1769
|
};
|
|
1646
1770
|
|
|
@@ -1736,7 +1860,7 @@ function bIfStatement(ifElseIfNode, cxt) {
|
|
|
1736
1860
|
elseBlock = bIfStatement(elseNode, cxt);
|
|
1737
1861
|
}
|
|
1738
1862
|
}
|
|
1739
|
-
return estreeToolkit.builders.ifStatement(expressionIrToEs(condition, cxt), bBlockStatement(children, cxt,
|
|
1863
|
+
return estreeToolkit.builders.ifStatement(expressionIrToEs(condition, cxt), bBlockStatement(children, cxt, !cxt.isSlotted), elseBlock);
|
|
1740
1864
|
}
|
|
1741
1865
|
const IfBlock = function IfBlock(node, cxt) {
|
|
1742
1866
|
return [bIfStatement(node, cxt)];
|
|
@@ -1751,12 +1875,15 @@ const IfBlock = function IfBlock(node, cxt) {
|
|
|
1751
1875
|
const bConditionalSlot = (esTemplateWithYield `
|
|
1752
1876
|
if (isLightDom) {
|
|
1753
1877
|
const isScopedSlot = ${ /* isScopedSlot */estreeToolkit.is.literal};
|
|
1878
|
+
const isSlotted = ${ /* isSlotted */estreeToolkit.is.literal};
|
|
1754
1879
|
// start bookend HTML comment for light DOM slot vfragment
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
// scoped slot factory has its own vfragment hence its own bookend
|
|
1758
|
-
if (isScopedSlot) {
|
|
1880
|
+
if (!isSlotted) {
|
|
1759
1881
|
yield '<!---->';
|
|
1882
|
+
|
|
1883
|
+
// scoped slot factory has its own vfragment hence its own bookend
|
|
1884
|
+
if (isScopedSlot) {
|
|
1885
|
+
yield '<!---->';
|
|
1886
|
+
}
|
|
1760
1887
|
}
|
|
1761
1888
|
|
|
1762
1889
|
const generators = lightSlottedContent?.[${ /* slotName */estreeToolkit.is.expression} ?? ""];
|
|
@@ -1772,14 +1899,16 @@ const bConditionalSlot = (esTemplateWithYield `
|
|
|
1772
1899
|
// TODO: default/fallback slot content
|
|
1773
1900
|
${ /* slot fallback content */estreeToolkit.is.statement}
|
|
1774
1901
|
}
|
|
1775
|
-
|
|
1776
|
-
// scoped slot factory has its own vfragment hence its own bookend
|
|
1777
|
-
if (isScopedSlot) {
|
|
1778
|
-
yield '<!---->';
|
|
1779
|
-
}
|
|
1780
1902
|
|
|
1781
1903
|
// end bookend HTML comment for light DOM slot vfragment
|
|
1782
|
-
|
|
1904
|
+
if (!isSlotted) {
|
|
1905
|
+
yield '<!---->';
|
|
1906
|
+
|
|
1907
|
+
// scoped slot factory has its own vfragment hence its own bookend
|
|
1908
|
+
if (isScopedSlot) {
|
|
1909
|
+
yield '<!---->';
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1783
1912
|
} else {
|
|
1784
1913
|
${ /* slot element AST */estreeToolkit.is.statement}
|
|
1785
1914
|
}
|
|
@@ -1794,7 +1923,8 @@ const Slot = function Slot(node, ctx) {
|
|
|
1794
1923
|
const slotAst = Element(node, ctx);
|
|
1795
1924
|
const slotChildren = irChildrenToEs(node.children, ctx);
|
|
1796
1925
|
const isScopedSlot = estreeToolkit.builders.literal(Boolean(slotBound));
|
|
1797
|
-
|
|
1926
|
+
const isSlotted = estreeToolkit.builders.literal(Boolean(ctx.isSlotted));
|
|
1927
|
+
return [bConditionalSlot(isScopedSlot, isSlotted, slotName, slotBound, slotChildren, slotAst)];
|
|
1798
1928
|
};
|
|
1799
1929
|
|
|
1800
1930
|
/*
|
|
@@ -1807,9 +1937,6 @@ const bBufferTextContent = (esTemplateWithYield `
|
|
|
1807
1937
|
didBufferTextContent = true;
|
|
1808
1938
|
textContentBuffer += massageTextContent(${ /* string value */estreeToolkit.is.expression});
|
|
1809
1939
|
`);
|
|
1810
|
-
function isLiteral(node) {
|
|
1811
|
-
return node.type === 'Literal';
|
|
1812
|
-
}
|
|
1813
1940
|
const Text = function Text(node, cxt) {
|
|
1814
1941
|
cxt.import(['htmlEscape', 'massageTextContent']);
|
|
1815
1942
|
const isLastInSeries = isLastConcatenatedNode(cxt);
|
|
@@ -1826,39 +1953,7 @@ const Text = function Text(node, cxt) {
|
|
|
1826
1953
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
1827
1954
|
*/
|
|
1828
1955
|
function createNewContext(templateOptions) {
|
|
1829
|
-
|
|
1830
|
-
const importMap = new Map();
|
|
1831
|
-
/**
|
|
1832
|
-
* Hoist an import declaration to the top of the file. If source is not specified, defaults to
|
|
1833
|
-
* `@lwc/ssr-runtime`.
|
|
1834
|
-
*/
|
|
1835
|
-
const _import = (imports, source = '@lwc/ssr-runtime') => {
|
|
1836
|
-
let specifiers;
|
|
1837
|
-
if (typeof imports === 'string') {
|
|
1838
|
-
specifiers = [[imports, undefined]];
|
|
1839
|
-
}
|
|
1840
|
-
else if (Array.isArray(imports)) {
|
|
1841
|
-
specifiers = imports.map((name) => [name, undefined]);
|
|
1842
|
-
}
|
|
1843
|
-
else {
|
|
1844
|
-
specifiers = Object.entries(imports);
|
|
1845
|
-
}
|
|
1846
|
-
let specifierMap = importMap.get(source);
|
|
1847
|
-
if (specifierMap) {
|
|
1848
|
-
for (const [imported, local] of specifiers) {
|
|
1849
|
-
specifierMap.set(imported, local);
|
|
1850
|
-
}
|
|
1851
|
-
}
|
|
1852
|
-
else {
|
|
1853
|
-
specifierMap = new Map(specifiers);
|
|
1854
|
-
importMap.set(source, specifierMap);
|
|
1855
|
-
}
|
|
1856
|
-
};
|
|
1857
|
-
const getImports = () => {
|
|
1858
|
-
return Array.from(importMap, ([source, specifierMap]) => {
|
|
1859
|
-
return bImportDeclaration(Object.fromEntries(specifierMap), source);
|
|
1860
|
-
});
|
|
1861
|
-
};
|
|
1956
|
+
const importManager = new ImportManager();
|
|
1862
1957
|
const localVarStack = [];
|
|
1863
1958
|
const pushLocalVars = (vars) => {
|
|
1864
1959
|
localVarStack.push(new Set(vars));
|
|
@@ -1878,13 +1973,13 @@ function createNewContext(templateOptions) {
|
|
|
1878
1973
|
return false;
|
|
1879
1974
|
};
|
|
1880
1975
|
return {
|
|
1881
|
-
getImports,
|
|
1976
|
+
getImports: () => importManager.getImportDeclarations(),
|
|
1882
1977
|
cxt: {
|
|
1883
1978
|
pushLocalVars,
|
|
1884
1979
|
popLocalVars,
|
|
1885
1980
|
isLocalVar,
|
|
1886
1981
|
templateOptions,
|
|
1887
|
-
import:
|
|
1982
|
+
import: importManager.add.bind(importManager),
|
|
1888
1983
|
},
|
|
1889
1984
|
};
|
|
1890
1985
|
}
|
|
@@ -2068,7 +2163,7 @@ function compileTemplate(src, filename, options, compilationMode) {
|
|
|
2068
2163
|
*/
|
|
2069
2164
|
function compileComponentForSSR(src, filename, options, mode = shared.DEFAULT_SSR_MODE) {
|
|
2070
2165
|
const tagName = shared.generateCustomElementTagName(options.namespace, options.name);
|
|
2071
|
-
const { code } = compileJS(src, filename, tagName, mode);
|
|
2166
|
+
const { code } = compileJS(src, filename, tagName, options, mode);
|
|
2072
2167
|
return { code, map: undefined };
|
|
2073
2168
|
}
|
|
2074
2169
|
function compileTemplateForSSR(src, filename, options, mode = shared.DEFAULT_SSR_MODE) {
|
|
@@ -2078,5 +2173,5 @@ function compileTemplateForSSR(src, filename, options, mode = shared.DEFAULT_SSR
|
|
|
2078
2173
|
|
|
2079
2174
|
exports.compileComponentForSSR = compileComponentForSSR;
|
|
2080
2175
|
exports.compileTemplateForSSR = compileTemplateForSSR;
|
|
2081
|
-
/** version: 8.12.
|
|
2176
|
+
/** version: 8.12.1 */
|
|
2082
2177
|
//# sourceMappingURL=index.cjs.js.map
|