@stencil/core 5.0.0-alpha.28 → 5.0.0-alpha.29

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.
Files changed (44) hide show
  1. package/dist/app-data/index.d.ts +1 -1
  2. package/dist/{client-CvcvHKz4.mjs → client-D1MsT-Rp.mjs} +373 -238
  3. package/dist/compiler/index.d.mts +2 -3
  4. package/dist/compiler/index.mjs +3 -3
  5. package/dist/compiler/utils/index.d.mts +272 -2
  6. package/dist/compiler/utils/index.mjs +4 -3
  7. package/dist/{compiler-BEGofLCO.mjs → compiler-BbS9TDF_.mjs} +1804 -1085
  8. package/dist/declarations/stencil-ext-modules.d.ts +5 -5
  9. package/dist/declarations/stencil-public-compiler.d.ts +108 -40
  10. package/dist/declarations/stencil-public-docs.d.ts +9 -0
  11. package/dist/declarations/stencil-public-runtime.d.ts +81 -6
  12. package/dist/fragment-Di1hWOC8.mjs +4 -0
  13. package/dist/{index-F3IidHM1.d.mts → index-BHj3EBl2.d.mts} +395 -312
  14. package/dist/{index-xAkMgLX_.d.ts → index-D2PAsXxx.d.ts} +133 -9
  15. package/dist/index-VK8okIiF.d.mts +108 -0
  16. package/dist/index.d.mts +4 -0
  17. package/dist/index.mjs +91 -2
  18. package/dist/jsx-runtime.mjs +2 -1
  19. package/dist/{node-BlgRcMMi.mjs → node-BQR4L-TG.mjs} +9 -7
  20. package/dist/reactive-controller-BdCpSAQP.d.mts +13 -0
  21. package/dist/{regular-expression-CFVJOTUh.mjs → regular-expression-XqU5zmPp.mjs} +20 -3
  22. package/dist/{chunk-z9aeyW2b.mjs → rolldown-runtime-BhDjJH2R.mjs} +1 -1
  23. package/dist/runtime/client/lazy.js +411 -165
  24. package/dist/runtime/client/runtime.d.ts +136 -9
  25. package/dist/runtime/client/runtime.js +411 -165
  26. package/dist/runtime/index.d.ts +5 -3
  27. package/dist/runtime/index.js +410 -163
  28. package/dist/runtime/server/index.d.mts +80 -8
  29. package/dist/runtime/server/index.mjs +333 -158
  30. package/dist/runtime/server/runner.d.mts +3 -0
  31. package/dist/runtime/server/runner.mjs +232 -308
  32. package/dist/signals/index.d.ts +2 -0
  33. package/dist/sys/node/index.d.mts +1 -2
  34. package/dist/sys/node/index.mjs +1 -1
  35. package/dist/sys/node/worker.d.mts +1 -1
  36. package/dist/sys/node/worker.mjs +6 -3
  37. package/dist/testing/index.d.mts +4 -9
  38. package/dist/testing/index.mjs +64 -46
  39. package/dist/util-BIa-iHnt.mjs +724 -0
  40. package/dist/validation-Dd3g77T5.mjs +778 -0
  41. package/package.json +27 -27
  42. package/dist/index-3fu7WQs4.d.mts +0 -205
  43. package/dist/validation-CtaOJgnM.mjs +0 -1458
  44. /package/{LICENSE.md → LICENSE} +0 -0
@@ -1,8 +1,9 @@
1
- import { n as __require } from "./chunk-z9aeyW2b.mjs";
2
- import { O as HYDRATED_CSS, f as scopeCss } from "./client-CvcvHKz4.mjs";
3
- import { $ as VALID_CONFIG_OUTPUT_TARGETS, C as ASSETS, D as COLLECTION_MANIFEST_FILE_NAME, E as COLLECTION_APP_DATA_FILE_NAME, F as DOCS_README, J as STANDALONE, L as EVENT_FLAGS, O as COPY, P as DOCS_JSON, Q as TYPES, R as GENERATED_DTS, T as COLLECTION, U as LOADER_BUNDLE, X as STYLE_EXT, Y as STATS, _ as sortBy, a as fromEntries, b as toTitleCase, d as isNumber$1, et as WATCH_FLAGS, f as isObject, h as noop, i as flatOne, j as DIST_LAZY, l as isFunction, m as mergeIntoWith, n as dashToPascalCase, o as isBoolean$1, p as isString$1, u as isIterable, x as unique, y as toDashCase, z as GLOBAL_STYLE } from "./regular-expression-CFVJOTUh.mjs";
4
- import { $ as loadTypeScriptDiagnostics, A as isOutputTargetCollection, B as isOutputTargetGlobalStyle, Ct as formatComponentRuntimeMeta, E as getComponentsDtsSrcFilePath, Et as byteSize, F as isOutputTargetDocsCustom, G as isOutputTargetStats, H as isOutputTargetSsr, I as isOutputTargetDocsCustomElementsManifest, J as isValidConfigOutputTarget, K as isOutputTargetTypes, L as isOutputTargetDocsJson, M as isOutputTargetCustom, N as isOutputTargetDistLazy, O as getComponentsFromModules, P as isOutputTargetDocs, Q as loadTypeScriptDiagnostic, R as isOutputTargetDocsReadme, S as ok, St as isGlob, T as filterExcludedComponents, Tt as stringifyRuntimeData, U as isOutputTargetSsrWasm, V as isOutputTargetLoaderBundle, W as isOutputTargetStandalone, Y as relativeImport, Z as augmentDiagnosticWithNode, _ as getSourceMappingUrlForEndOfFile, _t as catchError, a as getTextDocs, at as relative$1, b as err, ct as isRolldownError, d as isTsxFile, dt as normalizeDiagnostics, et as join$2, f as parsePackageJson, ft as splitLineBreaks, g as getInlineSourceMappingUrlLinker, gt as buildWarn, h as isRemoteUrl, ht as buildJsonFileError, i as generatePreamble, it as normalizePath, j as isOutputTargetCopy, k as isOutputTargetAssets, lt as loadRolldownDiagnostics, m as readPackageJson, mt as buildError, n as addDocBlock, nt as normalizeFsPath, o as hasDependency, ot as resolve$2, p as readOnlyArrayHasStringMember, q as isOutputTargetWww, r as createJsVarName, rt as normalizeFsPathQuery, s as isDtsFile, st as createOnWarnFn, t as validateComponentTag, u as isTsFile, vt as hasError, w as filterActiveTargets, x as map, xt as isRootPath, y as rolldownToStencilSourceMap, yt as hasWarning, z as isOutputTargetDocsVscode } from "./validation-CtaOJgnM.mjs";
5
- import { i as CustomElementsExportBehaviorOptions, o as buildEvents, r as createNodeLogger, t as createNodeSys } from "./node-BlgRcMMi.mjs";
1
+ import { n as __require } from "./rolldown-runtime-BhDjJH2R.mjs";
2
+ import { O as HYDRATED_CSS, f as scopeCss } from "./client-D1MsT-Rp.mjs";
3
+ import { $ as TYPES, B as GLOBAL_STYLE, C as ASSETS, D as COLLECTION_MANIFEST_FILE_NAME, E as COLLECTION_APP_DATA_FILE_NAME, F as DOCS_JSON, I as DOCS_README, O as COPY, R as EVENT_FLAGS, T as COLLECTION, W as LOADER_BUNDLE, X as STATS, Y as STANDALONE, Z as STYLE_EXT, _ as sortBy, a as fromEntries, b as toTitleCase, d as isNumber$1, et as VALID_CONFIG_OUTPUT_TARGETS, f as isObject, h as noop, i as flatOne, j as DIST_LAZY, l as isFunction, m as mergeIntoWith, n as dashToPascalCase, o as isBoolean$1, p as isString$1, tt as WATCH_FLAGS, u as isIterable, x as unique, y as toDashCase, z as GENERATED_DTS } from "./regular-expression-XqU5zmPp.mjs";
4
+ import { S as formatComponentRuntimeMeta, T as byteSize, _ as loadRolldownDiagnostics, a as getSourceMappingUrlForEndOfFile, b as splitLineBreaks, c as err, f as augmentDiagnosticWithNode, g as isRolldownError, h as createOnWarnFn, i as getInlineSourceMappingUrlLinker, l as map, m as loadTypeScriptDiagnostics, n as validateComponentTag, p as loadTypeScriptDiagnostic, r as isRemoteUrl, s as rolldownToStencilSourceMap, t as validateComponentModes, u as ok, w as stringifyRuntimeData, x as isRootPath, y as normalizeDiagnostics } from "./validation-Dd3g77T5.mjs";
5
+ import { $ as catchError, A as isOutputTargetDocsVscode, B as relativeImport, C as isOutputTargetDistLazy, D as isOutputTargetDocsCustomElementsManifest, E as isOutputTargetDocsCustom, F as isOutputTargetStandalone, G as normalizeFsPathQuery, H as join$2, I as isOutputTargetStats, J as resolve$2, K as normalizePath, L as isOutputTargetTypes, M as isOutputTargetLoaderBundle, N as isOutputTargetSsr, O as isOutputTargetDocsJson, P as isOutputTargetSsrWasm, Q as buildWarn, R as isOutputTargetWww, S as isOutputTargetCustom, T as isOutputTargetDocsAgentSkill, W as normalizeFsPath, X as buildError, Z as buildJsonFileError, a as hasDependency, b as isOutputTargetCollection, d as parsePackageJson, et as hasError, f as readOnlyArrayHasStringMember, g as getComponentsDtsSrcFilePath, h as filterExcludedComponents, i as getTextDocs, j as isOutputTargetGlobalStyle, k as isOutputTargetDocsReadme, l as isTsFile, m as filterActiveTargets, n as createJsVarName, o as isDtsFile, p as readPackageJson, q as relative$1, r as generatePreamble, rt as isGlob, t as addDocBlock, tt as hasWarning, u as isTsxFile, v as getComponentsFromModules, w as isOutputTargetDocs, x as isOutputTargetCopy, y as isOutputTargetAssets, z as isValidConfigOutputTarget } from "./util-BIa-iHnt.mjs";
6
+ import { i as CustomElementsExportBehaviorOptions, o as buildEvents, r as createNodeLogger, t as createNodeSys } from "./node-BQR4L-TG.mjs";
6
7
  import ts, { default as ts$1 } from "typescript";
7
8
  import { readFileSync } from "node:fs";
8
9
  import { basename, dirname, isAbsolute, join, resolve } from "node:path";
@@ -28,9 +29,9 @@ import { createJiti } from "jiti";
28
29
  import * as process$1 from "process";
29
30
  import { dataToEsm } from "@rollup/pluginutils";
30
31
  //#region src/version.ts
31
- const version = "5.0.0-alpha.28";
32
- const buildId = "1784191171";
33
- const vermoji = "🎳";
32
+ const version = "5.0.0-alpha.29";
33
+ const buildId = "1786998516";
34
+ const vermoji = "👾";
34
35
  /**
35
36
  * Get the installed version of a tool/dependency.
36
37
  * Handles packages with exports maps that point to subdirectories.
@@ -41,7 +42,9 @@ const vermoji = "🎳";
41
42
  */
42
43
  function getToolVersion(name) {
43
44
  try {
44
- let dir = dirname(fileURLToPath(import.meta.resolve(name)));
45
+ const entryUrl = import.meta.resolve(name);
46
+ const entryPath = fileURLToPath(entryUrl);
47
+ let dir = dirname(entryPath);
45
48
  while (dir !== dirname(dir)) {
46
49
  const pkgPath = join(dir, "package.json");
47
50
  try {
@@ -161,7 +164,8 @@ const getModuleLegacy = (compilerCtx, sourceFilePath) => {
161
164
  else {
162
165
  const sourceFileDir = dirname$1(sourceFilePath);
163
166
  const sourceFileExt = extname(sourceFilePath);
164
- const jsFilePath = join$2(sourceFileDir, basename$1(sourceFilePath, sourceFileExt) + ".js");
167
+ const sourceFileName = basename$1(sourceFilePath, sourceFileExt);
168
+ const jsFilePath = join$2(sourceFileDir, sourceFileName + ".js");
165
169
  const moduleFile = {
166
170
  sourceFilePath,
167
171
  jsFilePath,
@@ -190,6 +194,7 @@ const getModuleLegacy = (compilerCtx, sourceFilePath) => {
190
194
  htmlAttrNames: [],
191
195
  htmlTagNames: [],
192
196
  htmlParts: [],
197
+ htmlSlots: [],
193
198
  isCollectionDependency: false,
194
199
  isLegacy: false,
195
200
  localImports: [],
@@ -491,7 +496,7 @@ const getModuleImports = (moduleMap, filePath, importedModules) => {
491
496
  * build - everything else is a component-derived flag that the consumer recomputes itself
492
497
  * by scanning all components (including those from the collection).
493
498
  */
494
- const COLLECTION_CONFIG_FLAGS = new Set([
499
+ const COLLECTION_CONFIG_FLAGS = /* @__PURE__ */ new Set([
495
500
  "lightDomPatches",
496
501
  "slotChildNodes",
497
502
  "slotCloneNode",
@@ -755,11 +760,12 @@ function hostRefElementInternalsPropAccess() {
755
760
  */
756
761
  const updateLazyComponentConstructor = (classMembers, classNode, moduleFile, cmp) => {
757
762
  const cstrMethodArgs = [ts.factory.createParameterDeclaration(void 0, void 0, ts.factory.createIdentifier(HOST_REF_ARG))];
758
- updateConstructor(classNode, classMembers, [
763
+ const cstrStatements = [
759
764
  registerInstanceStatement(moduleFile),
760
765
  ...addCreateEvents(moduleFile, cmp),
761
766
  ...createLazyAttachInternalsBinding(cmp)
762
- ], cstrMethodArgs);
767
+ ];
768
+ updateConstructor(classNode, classMembers, cstrStatements, cstrMethodArgs);
763
769
  };
764
770
  /**
765
771
  * Create a statement containing an expression calling the `registerInstance`
@@ -953,19 +959,7 @@ function findTypeWithName(module, typeName) {
953
959
  function getOriginalTypeName(identifier, checker) {
954
960
  const possiblyAliasedSymbol = checker.getSymbolAtLocation(identifier);
955
961
  if (!possiblyAliasedSymbol) return;
956
- return unalias(possiblyAliasedSymbol, checker).getName();
957
- }
958
- /**
959
- * Check if a symbol is an alias of another symbol and, if so, use the
960
- * {@link ts.TypeChecker} to resolve the original. If not, just return the same
961
- * symbol.
962
- *
963
- * @param symbol the symbol of interest
964
- * @param checker a {@link ts.TypeChecker}
965
- * @returns a de-aliased symbol
966
- */
967
- function unalias(symbol, checker) {
968
- return symbol.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
962
+ return resolveAliasedSymbol(checker, possiblyAliasedSymbol).getName();
969
963
  }
970
964
  /**
971
965
  * Check that a {@link ts.Node} is a type-declaration-like node. For our
@@ -1266,38 +1260,41 @@ const objectLiteralToObjectMap = (objectLiteral, typeChecker, diagnostics, error
1266
1260
  const propName = getTextOfPropertyName(propAssignment.name);
1267
1261
  let val;
1268
1262
  if (ts.isShorthandPropertyAssignment(propAssignment)) val = getIdentifierValue(propName);
1269
- else if (ts.isPropertyAssignment(propAssignment)) if (ts.isCallExpression(propAssignment.initializer) && typeChecker && (ts.isIdentifier(propAssignment.initializer.expression) && propAssignment.initializer.expression.text === "resolveVar" || ts.isPropertyAccessExpression(propAssignment.initializer.expression) && ts.isIdentifier(propAssignment.initializer.expression.name) && propAssignment.initializer.expression.name.text === "resolveVar")) if (propAssignment.initializer.arguments.length === 1) val = resolveVarInObjectLiteral(propAssignment.initializer.arguments[0], typeChecker, diagnostics, propAssignment.initializer);
1270
- else val = propAssignment.initializer;
1271
- else switch (propAssignment.initializer.kind) {
1272
- case ts.SyntaxKind.ArrayLiteralExpression:
1273
- val = arrayLiteralToArray(propAssignment.initializer);
1274
- break;
1275
- case ts.SyntaxKind.ObjectLiteralExpression:
1276
- val = objectLiteralToObjectMap(propAssignment.initializer, typeChecker, diagnostics, errorNode);
1277
- break;
1278
- case ts.SyntaxKind.StringLiteral:
1279
- val = propAssignment.initializer.text;
1280
- break;
1281
- case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
1282
- val = propAssignment.initializer.text;
1283
- break;
1284
- case ts.SyntaxKind.TrueKeyword:
1285
- val = true;
1286
- break;
1287
- case ts.SyntaxKind.FalseKeyword:
1288
- val = false;
1289
- break;
1290
- case ts.SyntaxKind.Identifier:
1291
- const escapedText = propAssignment.initializer.escapedText;
1292
- if (escapedText === "String") val = String;
1293
- else if (escapedText === "Number") val = Number;
1294
- else if (escapedText === "Boolean") val = Boolean;
1295
- else if (escapedText === "undefined") val = void 0;
1296
- else if (escapedText === "null") val = null;
1297
- else val = getIdentifierValue(propAssignment.initializer.escapedText);
1298
- break;
1299
- case ts.SyntaxKind.PropertyAccessExpression:
1300
- default: val = propAssignment.initializer;
1263
+ else if (ts.isPropertyAssignment(propAssignment)) {
1264
+ if (ts.isCallExpression(propAssignment.initializer) && typeChecker && (ts.isIdentifier(propAssignment.initializer.expression) && propAssignment.initializer.expression.text === "resolveVar" || ts.isPropertyAccessExpression(propAssignment.initializer.expression) && ts.isIdentifier(propAssignment.initializer.expression.name) && propAssignment.initializer.expression.name.text === "resolveVar")) {
1265
+ if (propAssignment.initializer.arguments.length === 1) val = resolveVarInObjectLiteral(propAssignment.initializer.arguments[0], typeChecker, diagnostics, propAssignment.initializer);
1266
+ else val = propAssignment.initializer;
1267
+ } else switch (propAssignment.initializer.kind) {
1268
+ case ts.SyntaxKind.ArrayLiteralExpression:
1269
+ val = arrayLiteralToArray(propAssignment.initializer);
1270
+ break;
1271
+ case ts.SyntaxKind.ObjectLiteralExpression:
1272
+ val = objectLiteralToObjectMap(propAssignment.initializer, typeChecker, diagnostics, errorNode);
1273
+ break;
1274
+ case ts.SyntaxKind.StringLiteral:
1275
+ val = propAssignment.initializer.text;
1276
+ break;
1277
+ case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
1278
+ val = propAssignment.initializer.text;
1279
+ break;
1280
+ case ts.SyntaxKind.TrueKeyword:
1281
+ val = true;
1282
+ break;
1283
+ case ts.SyntaxKind.FalseKeyword:
1284
+ val = false;
1285
+ break;
1286
+ case ts.SyntaxKind.Identifier:
1287
+ const escapedText = propAssignment.initializer.escapedText;
1288
+ if (escapedText === "String") val = String;
1289
+ else if (escapedText === "Number") val = Number;
1290
+ else if (escapedText === "Boolean") val = Boolean;
1291
+ else if (escapedText === "undefined") val = void 0;
1292
+ else if (escapedText === "null") val = null;
1293
+ else val = getIdentifierValue(propAssignment.initializer.escapedText);
1294
+ break;
1295
+ case ts.SyntaxKind.PropertyAccessExpression:
1296
+ default: val = propAssignment.initializer;
1297
+ }
1301
1298
  }
1302
1299
  final[propName] = val;
1303
1300
  }
@@ -1315,7 +1312,8 @@ const objectLiteralToObjectMap = (objectLiteral, typeChecker, diagnostics, error
1315
1312
  */
1316
1313
  const resolveVarInObjectLiteral = (node, typeChecker, _diagnostics, _errorNode) => {
1317
1314
  if (ts.isIdentifier(node)) {
1318
- const symbol = typeChecker.getSymbolAtLocation(node);
1315
+ let symbol = typeChecker.getSymbolAtLocation(node);
1316
+ if (symbol && symbol.flags & ts.SymbolFlags.Alias) symbol = typeChecker.getAliasedSymbol(symbol);
1319
1317
  if (!symbol || !symbol.valueDeclaration) throw new Error(`resolveVar() cannot resolve the value of "${node.text}" at compile time. Only const variables and object properties with string literal values are supported.`);
1320
1318
  const declaration = symbol.valueDeclaration;
1321
1319
  if (ts.isVariableDeclaration(declaration)) {
@@ -1405,6 +1403,14 @@ const getEntityName = (entity) => {
1405
1403
  else return getEntityName(entity.left);
1406
1404
  };
1407
1405
  /**
1406
+ * Resolve a TypeScript alias to its original symbol.
1407
+ *
1408
+ * @param checker a TypeScript type checker
1409
+ * @param symbol the symbol to resolve, if one was found
1410
+ * @returns the original symbol for an alias, the provided symbol otherwise, or `undefined`
1411
+ */
1412
+ const resolveAliasedSymbol = (checker, symbol) => symbol && (symbol.flags & ts.SymbolFlags.Alias) !== 0 ? checker.getAliasedSymbol(symbol) : symbol;
1413
+ /**
1408
1414
  * Recursively walks the provided AST to collect all TypeScript type references that are found
1409
1415
  *
1410
1416
  * @param checker a {@link ts.TypeChecker} instance
@@ -1431,6 +1437,11 @@ const getAllTypeReferences = (checker, node) => {
1431
1437
  type: checker.getTypeFromTypeNode(typeRef)
1432
1438
  });
1433
1439
  });
1440
+ } else if (ts.isTypeQueryNode(currentNode) && ts.isIdentifier(currentNode.exprName)) {
1441
+ if (resolveAliasedSymbol(checker, checker.getSymbolAtLocation(currentNode.exprName))?.declarations?.some((declaration) => ts.isEnumDeclaration(declaration) || ts.isClassDeclaration(declaration))) referencedTypes.push({
1442
+ name: getEntityName(currentNode.exprName),
1443
+ type: checker.getTypeAtLocation(currentNode.exprName)
1444
+ });
1434
1445
  }
1435
1446
  return ts.forEachChild(currentNode, visit);
1436
1447
  };
@@ -1471,30 +1482,50 @@ const getTypeReferenceLocation = (typeName, type, sourceFile, checker, program)
1471
1482
  const importName = importElement.name;
1472
1483
  const originalTypeName = getOriginalTypeName(importName, checker);
1473
1484
  const importedAs = importElement.propertyName ? importElement.propertyName.getText() : typeName;
1474
- const typeDecl = findTypeWithName(importHomeModule, originalTypeName);
1475
- type = checker.getTypeAtLocation(typeDecl);
1485
+ const importedSymbol = resolveAliasedSymbol(checker, checker.getSymbolAtLocation(importName));
1486
+ const declaration = importedSymbol?.valueDeclaration ?? importedSymbol?.declarations?.[0];
1487
+ const enumOrClassDeclaration = declaration && (ts.isClassDeclaration(declaration) || ts.isEnumDeclaration(declaration)) ? declaration : void 0;
1488
+ if (importedSymbol && enumOrClassDeclaration) type = checker.getTypeOfSymbolAtLocation(importedSymbol, enumOrClassDeclaration);
1489
+ else {
1490
+ const typeDecl = findTypeWithName(importHomeModule, originalTypeName);
1491
+ if (typeDecl) type = checker.getTypeAtLocation(typeDecl);
1492
+ }
1493
+ const typeSourceFile = enumOrClassDeclaration?.getSourceFile() ?? importHomeModule;
1476
1494
  return {
1477
1495
  location: "import",
1478
1496
  path: localImportPath,
1479
- id: addToLibrary(type, originalTypeName, checker, normalizePath(importHomeModule.fileName, false)),
1497
+ id: addToLibrary(type, originalTypeName, checker, normalizePath(typeSourceFile.fileName, false)),
1480
1498
  referenceLocation: importedAs
1481
1499
  };
1482
1500
  }
1483
1501
  }
1484
- if (sourceFile.statements.some((st) => {
1502
+ const localExport = sourceFile.statements.reduce((exportInfo, st) => {
1503
+ if (exportInfo) return exportInfo;
1504
+ if (ts.isExportAssignment(st) && !st.isExportEquals && ts.isIdentifier(st.expression) && st.expression.getText() === typeName) return { isDefault: true };
1505
+ if (ts.isExportDeclaration(st) && !st.moduleSpecifier && ts.isNamedExports(st.exportClause)) {
1506
+ const exportSpecifier = st.exportClause.elements.find((element) => (element.propertyName ?? element.name).getText() === typeName);
1507
+ if (exportSpecifier) {
1508
+ const exportedName = exportSpecifier.name.getText();
1509
+ return exportedName === "default" ? { isDefault: true } : { referenceLocation: exportedName === typeName ? void 0 : exportedName };
1510
+ }
1511
+ }
1485
1512
  const statementModifiers = retrieveTsModifiers(st);
1486
- const isDeclarationExported = (statement) => statement.name.getText() === typeName && Array.isArray(statementModifiers) && statementModifiers.some((mod) => mod.kind === ts.SyntaxKind.ExportKeyword);
1513
+ const isDeclarationExported = (statement) => statement.name?.getText() === typeName && Array.isArray(statementModifiers) && statementModifiers.some((mod) => mod.kind === ts.SyntaxKind.ExportKeyword);
1487
1514
  const isInterfaceDeclarationExported = ts.isInterfaceDeclaration(st) && isDeclarationExported(st);
1488
1515
  const isTypeAliasDeclarationExported = ts.isTypeAliasDeclaration(st) && isDeclarationExported(st);
1489
1516
  const isEnumDeclarationExported = ts.isEnumDeclaration(st) && isDeclarationExported(st);
1490
- const isTypeInExportDeclaration = ts.isExportDeclaration(st) && ts.isNamedExports(st.exportClause) && st.exportClause.elements.some((nee) => nee.name.getText() === typeName);
1491
- return isInterfaceDeclarationExported || isTypeAliasDeclarationExported || isEnumDeclarationExported || isTypeInExportDeclaration;
1492
- })) {
1517
+ const isClassDeclarationExported = ts.isClassDeclaration(st) && isDeclarationExported(st);
1518
+ if (!(isInterfaceDeclarationExported || isTypeAliasDeclarationExported || isEnumDeclarationExported || isClassDeclarationExported)) return;
1519
+ return statementModifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword) ? { isDefault: true } : {};
1520
+ }, void 0);
1521
+ if (localExport) {
1493
1522
  const id = addToLibrary(type, typeName, checker, sourceFile.fileName);
1494
1523
  return {
1495
1524
  location: "local",
1496
1525
  path: sourceFile.fileName,
1497
- id
1526
+ id,
1527
+ ...localExport.isDefault ? { isDefault: true } : {},
1528
+ ...localExport.referenceLocation ? { referenceLocation: localExport.referenceLocation } : {}
1498
1529
  };
1499
1530
  }
1500
1531
  const defaultImportDeclaration = sourceFile.statements.find((st) => {
@@ -1504,19 +1535,19 @@ const getTypeReferenceLocation = (typeName, type, sourceFile, checker, program)
1504
1535
  });
1505
1536
  if (defaultImportDeclaration) {
1506
1537
  const localImportPath = defaultImportDeclaration.moduleSpecifier.text;
1507
- const options = program.getCompilerOptions();
1508
- const importHomeModule = getHomeModule(sourceFile, localImportPath, options, ts.createCompilerHost(options), program);
1509
- if (importHomeModule) {
1510
- if (importHomeModule.statements.find((st) => ts.isExportAssignment(st) && !st.isExportEquals && ts.isIdentifier(st.expression) && st.expression.getText() === typeName)) {
1511
- const typeDecl = findTypeWithName(importHomeModule, typeName);
1512
- type = checker.getTypeAtLocation(typeDecl);
1513
- return {
1514
- location: "import",
1515
- path: localImportPath,
1516
- id: addToLibrary(type, typeName, checker, normalizePath(importHomeModule.fileName, false)),
1517
- isDefault: true
1518
- };
1519
- }
1538
+ const defaultImportName = defaultImportDeclaration.importClause.name;
1539
+ const importedSymbol = resolveAliasedSymbol(checker, checker.getSymbolAtLocation(defaultImportName));
1540
+ const declaration = importedSymbol?.valueDeclaration ?? importedSymbol?.declarations?.[0];
1541
+ if (importedSymbol && declaration) {
1542
+ if (ts.isClassDeclaration(declaration) || ts.isEnumDeclaration(declaration)) type = checker.getTypeOfSymbolAtLocation(importedSymbol, declaration);
1543
+ const declarationNodeName = declaration.name;
1544
+ const declarationName = declarationNodeName && ts.isIdentifier(declarationNodeName) ? declarationNodeName.getText() : importedSymbol.getName();
1545
+ return {
1546
+ location: "import",
1547
+ path: localImportPath,
1548
+ id: addToLibrary(type, declarationName === "default" ? typeName : declarationName, checker, normalizePath(declaration.getSourceFile().fileName, false)),
1549
+ isDefault: true
1550
+ };
1520
1551
  }
1521
1552
  }
1522
1553
  return {
@@ -1561,7 +1592,8 @@ const getTypeReferenceLocation = (typeName, type, sourceFile, checker, program)
1561
1592
  */
1562
1593
  const resolveType = (checker, type, typeNode) => {
1563
1594
  if (typeNode && ts.isArrayTypeNode(typeNode)) {
1564
- const elementResolved = resolveType(checker, checker.getTypeFromTypeNode(typeNode.elementType), typeNode.elementType);
1595
+ const elementType = checker.getTypeFromTypeNode(typeNode.elementType);
1596
+ const elementResolved = resolveType(checker, elementType, typeNode.elementType);
1565
1597
  return elementResolved.includes(" | ") ? `(${elementResolved})[]` : `${elementResolved}[]`;
1566
1598
  }
1567
1599
  const set = /* @__PURE__ */ new Set();
@@ -1615,13 +1647,18 @@ const parseDocsType = (checker, type, parts) => {
1615
1647
  const elemStr = sortedParts.join(" | ");
1616
1648
  parts.add(sortedParts.length > 1 ? `(${elemStr})[]` : `${elemStr}[]`);
1617
1649
  } else parts.add(typeToString(checker, type));
1618
- } else if (type.aliasSymbol) if (type.aliasTypeArguments && type.aliasTypeArguments.length > 0) type.aliasTypeArguments.forEach((argType) => {
1619
- parseDocsType(checker, argType, parts);
1620
- });
1621
- else if (type.aliasSymbol.declarations && type.aliasSymbol.declarations.length > 0) {
1622
- const aliasedType = checker.getTypeAtLocation(type.aliasSymbol.declarations[0]);
1623
- if (aliasedType && aliasedType !== type) parseDocsType(checker, aliasedType, parts);
1624
- else {
1650
+ } else if (type.aliasSymbol) {
1651
+ if (type.aliasTypeArguments && type.aliasTypeArguments.length > 0) type.aliasTypeArguments.forEach((argType) => {
1652
+ parseDocsType(checker, argType, parts);
1653
+ });
1654
+ else if (type.aliasSymbol.declarations && type.aliasSymbol.declarations.length > 0) {
1655
+ const aliasedType = checker.getTypeAtLocation(type.aliasSymbol.declarations[0]);
1656
+ if (aliasedType && aliasedType !== type) parseDocsType(checker, aliasedType, parts);
1657
+ else {
1658
+ const text = typeToString(checker, type);
1659
+ parts.add(text);
1660
+ }
1661
+ } else {
1625
1662
  const text = typeToString(checker, type);
1626
1663
  parts.add(text);
1627
1664
  }
@@ -1629,10 +1666,6 @@ const parseDocsType = (checker, type, parts) => {
1629
1666
  const text = typeToString(checker, type);
1630
1667
  parts.add(text);
1631
1668
  }
1632
- else {
1633
- const text = typeToString(checker, type);
1634
- parts.add(text);
1635
- }
1636
1669
  };
1637
1670
  /**
1638
1671
  * Retrieves a Stencil `Module` entity from the compiler context for a given TypeScript `SourceFile`
@@ -1660,7 +1693,8 @@ const getComponentMeta = (compilerCtx, tsSourceFile, node) => {
1660
1693
  if (meta) return meta;
1661
1694
  const moduleFile = getModuleFromSourceFile(compilerCtx, tsSourceFile);
1662
1695
  if (moduleFile != null && node.members != null) {
1663
- const tagName = getComponentTagName(node.members.filter(isStaticGetter));
1696
+ const staticMembers = node.members.filter(isStaticGetter);
1697
+ const tagName = getComponentTagName(staticMembers);
1664
1698
  if (typeof tagName === "string") return moduleFile.cmps.find((cmp) => cmp.tagName === tagName);
1665
1699
  }
1666
1700
  };
@@ -2102,7 +2136,8 @@ const generateAppDataModule = (build, config) => {
2102
2136
  return `export const BUILD = ${JSON.stringify(build, null, 2)};\nexport const Env = ${JSON.stringify(config.env ?? {})};\nexport const NAMESPACE = ${JSON.stringify(config.fsNamespace)};\n`;
2103
2137
  };
2104
2138
  const serializeCollectionManifest = (config, compilerCtx, buildCtx) => {
2105
- const buildFlags = getBuildFeatures(buildCtx.moduleFiles.filter((mod) => !mod.isCollectionDependency).flatMap((mod) => mod.cmps));
2139
+ const localCmps = buildCtx.moduleFiles.filter((mod) => !mod.isCollectionDependency).flatMap((mod) => mod.cmps);
2140
+ const buildFlags = getBuildFeatures(localCmps);
2106
2141
  buildFlags.hydrateClientSide = config.outputTargets.some(isOutputTargetSsr);
2107
2142
  const ldp = config.compat?.lightDomPatches ?? true;
2108
2143
  if (buildFlags.slotRelocation && ldp !== false) {
@@ -2148,10 +2183,11 @@ const serializeCollectionManifest = (config, compilerCtx, buildCtx) => {
2148
2183
  return collectionManifest;
2149
2184
  };
2150
2185
  const serializeCollectionDependencies = (compilerCtx) => {
2151
- return sortBy(compilerCtx.collections.map((c) => ({
2186
+ const collectionDeps = compilerCtx.collections.map((c) => ({
2152
2187
  name: c.collectionName,
2153
2188
  tags: flatOne(c.moduleFiles.map((m) => m.cmps)).map((cmp) => cmp.tagName).sort()
2154
- })), (item) => item.name);
2189
+ }));
2190
+ return sortBy(collectionDeps, (item) => item.name);
2155
2191
  };
2156
2192
  //#endregion
2157
2193
  //#region src/compiler/output-targets/copy/local-copy-tasks.ts
@@ -2160,8 +2196,10 @@ const getSrcAbsPath = (config, src) => {
2160
2196
  return join$2(config.srcDir, src);
2161
2197
  };
2162
2198
  const getDestAbsPath = (src, destAbsPath, destRelPath) => {
2163
- if (destRelPath) if (isAbsolute$1(destRelPath)) return destRelPath;
2164
- else return join$2(destAbsPath, destRelPath);
2199
+ if (destRelPath) {
2200
+ if (isAbsolute$1(destRelPath)) return destRelPath;
2201
+ else return join$2(destAbsPath, destRelPath);
2202
+ }
2165
2203
  if (isAbsolute$1(src)) throw new Error(`copy task, "dest" property must exist if "src" property is an absolute path: ${src}`);
2166
2204
  return destAbsPath;
2167
2205
  };
@@ -2355,6 +2393,7 @@ const setPackageVersionByContent = (pkgVersions, pkgContent) => {
2355
2393
  if (pkg.name && pkg.version) setPackageVersion(pkgVersions, pkg.name, pkg.version);
2356
2394
  } catch {}
2357
2395
  };
2396
+ const isNodeModulePath = (p) => normalizePath(p).split("/").includes("node_modules");
2358
2397
  const getModuleId = (orgImport) => {
2359
2398
  if (orgImport.startsWith("~")) orgImport = orgImport.substring(1);
2360
2399
  const splt = orgImport.split("/");
@@ -2446,6 +2485,54 @@ const createCustomResolverAsync = (sys, inMemoryFs, exts) => {
2446
2485
  //#endregion
2447
2486
  //#region src/compiler/style/style-utils.ts
2448
2487
  /**
2488
+ * Wrap CSS content according to the modifiers trailing an `@import` specifier
2489
+ * (`layer(name)`, `supports(condition)`, and/or a media query), mirroring what
2490
+ * `@import url(...) layer(name) supports(condition) (media);` would do natively.
2491
+ *
2492
+ * @param cssText the CSS content to wrap
2493
+ * @param modifiers the raw modifier string following the import specifier, if any
2494
+ * @returns cssText wrapped in @layer/@media/@supports blocks as needed
2495
+ */
2496
+ const wrapCssWithImportModifiers = (cssText, modifiers) => {
2497
+ if (!modifiers?.trim()) return cssText;
2498
+ let remaining = modifiers.trim();
2499
+ let replacement = cssText;
2500
+ let layerName = "";
2501
+ let supportsCondition = "";
2502
+ const layerMatch = remaining.match(/layer\(([^)]+)\)/);
2503
+ if (layerMatch) {
2504
+ layerName = layerMatch[1].trim();
2505
+ remaining = remaining.replace(/layer\([^)]+\)/, "").trim();
2506
+ }
2507
+ let depth = 0;
2508
+ let startIdx = -1;
2509
+ let endIdx = -1;
2510
+ const supportsIdx = remaining.indexOf("supports(");
2511
+ if (supportsIdx !== -1) {
2512
+ startIdx = supportsIdx + 9;
2513
+ for (let i = startIdx; i < remaining.length; i++) {
2514
+ if (remaining[i] === "(") depth++;
2515
+ if (remaining[i] === ")") {
2516
+ if (depth === 0) {
2517
+ endIdx = i;
2518
+ break;
2519
+ }
2520
+ depth--;
2521
+ }
2522
+ }
2523
+ if (endIdx !== -1) {
2524
+ supportsCondition = remaining.substring(startIdx, endIdx).trim();
2525
+ remaining = remaining.substring(0, supportsIdx) + remaining.substring(endIdx + 1);
2526
+ remaining = remaining.trim();
2527
+ }
2528
+ }
2529
+ const mediaQuery = remaining.trim();
2530
+ if (layerName) replacement = `@layer ${layerName} {\n${replacement}\n}`;
2531
+ if (mediaQuery) replacement = `@media ${mediaQuery} {\n${replacement}\n}`;
2532
+ if (supportsCondition) replacement = `@supports (${supportsCondition}) {\n${replacement}\n}`;
2533
+ return replacement;
2534
+ };
2535
+ /**
2449
2536
  * Strip out comments from some CSS
2450
2537
  *
2451
2538
  * @param input the string we'd like to de-comment
@@ -2585,7 +2672,8 @@ const getCssImports = async (config, compilerCtx, buildCtx, filePath, styleText)
2585
2672
  cssImportData.filePath += `.${importeeExt}`;
2586
2673
  if (importeeExt === "scss") {
2587
2674
  const fileName = "_" + basename$1(cssImportData.filePath);
2588
- cssImportData.altFilePath = normalizePath(join$2(dirname$1(cssImportData.filePath), fileName));
2675
+ const dirPath = dirname$1(cssImportData.filePath);
2676
+ cssImportData.altFilePath = normalizePath(join$2(dirPath, fileName));
2589
2677
  }
2590
2678
  }
2591
2679
  if (cssImportData.filePath !== "") imports.push(cssImportData);
@@ -2636,44 +2724,7 @@ const isLocalCssImport$1 = (srcImport) => {
2636
2724
  const replaceImportDeclarations = (styleText, cssImports, isCssEntry) => {
2637
2725
  for (const cssImport of cssImports) if (isCssEntry) {
2638
2726
  if (typeof cssImport.styleText === "string") {
2639
- let replacement = cssImport.styleText;
2640
- if (cssImport.modifiers) {
2641
- let modifiers = cssImport.modifiers;
2642
- let layerName = "";
2643
- let supportsCondition = "";
2644
- let mediaQuery = "";
2645
- const layerMatch = modifiers.match(/layer\(([^)]+)\)/);
2646
- if (layerMatch) {
2647
- layerName = layerMatch[1].trim();
2648
- modifiers = modifiers.replace(/layer\([^)]+\)/, "").trim();
2649
- }
2650
- let depth = 0;
2651
- let startIdx = -1;
2652
- let endIdx = -1;
2653
- const supportsIdx = modifiers.indexOf("supports(");
2654
- if (supportsIdx !== -1) {
2655
- startIdx = supportsIdx + 9;
2656
- for (let i = startIdx; i < modifiers.length; i++) {
2657
- if (modifiers[i] === "(") depth++;
2658
- if (modifiers[i] === ")") {
2659
- if (depth === 0) {
2660
- endIdx = i;
2661
- break;
2662
- }
2663
- depth--;
2664
- }
2665
- }
2666
- if (endIdx !== -1) {
2667
- supportsCondition = modifiers.substring(startIdx, endIdx).trim();
2668
- modifiers = modifiers.substring(0, supportsIdx) + modifiers.substring(endIdx + 1);
2669
- modifiers = modifiers.trim();
2670
- }
2671
- }
2672
- mediaQuery = modifiers.trim();
2673
- if (layerName) replacement = `@layer ${layerName} {\n${replacement}\n}`;
2674
- if (mediaQuery) replacement = `@media ${mediaQuery} {\n${replacement}\n}`;
2675
- if (supportsCondition) replacement = `@supports (${supportsCondition}) {\n${replacement}\n}`;
2676
- }
2727
+ const replacement = wrapCssWithImportModifiers(cssImport.styleText, cssImport.modifiers);
2677
2728
  styleText = styleText.replace(cssImport.srcImport, replacement);
2678
2729
  }
2679
2730
  } else if (typeof cssImport.updatedImport === "string") styleText = styleText.replace(cssImport.srcImport, cssImport.updatedImport);
@@ -2727,7 +2778,8 @@ const runPluginTransforms = async (config, compilerCtx, buildCtx, id, cmp) => {
2727
2778
  cache: compilerCtx.cache,
2728
2779
  diagnostics: []
2729
2780
  };
2730
- const sourceText = await runPluginLoad(pluginCtx, await runPluginResolveId(pluginCtx, id));
2781
+ const resolvedId = await runPluginResolveId(pluginCtx, id);
2782
+ const sourceText = await runPluginLoad(pluginCtx, resolvedId);
2731
2783
  if (!isString$1(sourceText)) {
2732
2784
  const diagnostic = buildError(buildCtx.diagnostics);
2733
2785
  diagnostic.header = `Unable to find "${basename$1(id)}"`;
@@ -2741,15 +2793,17 @@ const runPluginTransforms = async (config, compilerCtx, buildCtx, id, cmp) => {
2741
2793
  };
2742
2794
  const isRawCssFile = transformResults.id.toLowerCase().endsWith(".css");
2743
2795
  const shouldParseCssDocs = cmp != null && config.outputTargets.some(isOutputTargetDocs);
2744
- if (isRawCssFile) if (shouldParseCssDocs && cmp != null) {
2745
- cmp.styleDocs = cmp.styleDocs || [];
2746
- const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, id, transformResults.code, cmp.styleDocs);
2747
- transformResults.code = cssParseResults.styleText;
2748
- transformResults.dependencies = cssParseResults.imports;
2749
- } else {
2750
- const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, id, transformResults.code);
2751
- transformResults.code = cssParseResults.styleText;
2752
- transformResults.dependencies = cssParseResults.imports;
2796
+ if (isRawCssFile) {
2797
+ if (shouldParseCssDocs && cmp != null) {
2798
+ cmp.styleDocs = cmp.styleDocs || [];
2799
+ const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, id, transformResults.code, cmp.styleDocs);
2800
+ transformResults.code = cssParseResults.styleText;
2801
+ transformResults.dependencies = cssParseResults.imports;
2802
+ } else {
2803
+ const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, id, transformResults.code);
2804
+ transformResults.code = cssParseResults.styleText;
2805
+ transformResults.dependencies = cssParseResults.imports;
2806
+ }
2753
2807
  }
2754
2808
  for (const plugin of pluginCtx.config?.plugins ?? []) if (isFunction(plugin.transform)) try {
2755
2809
  let pluginTransformResults;
@@ -2757,29 +2811,33 @@ const runPluginTransforms = async (config, compilerCtx, buildCtx, id, cmp) => {
2757
2811
  if (results != null) {
2758
2812
  if (isFunction(results.then)) pluginTransformResults = await results;
2759
2813
  else pluginTransformResults = results;
2760
- if (pluginTransformResults != null) if (isString$1(pluginTransformResults)) transformResults.code = pluginTransformResults;
2761
- else {
2762
- if (isString$1(pluginTransformResults.code)) transformResults.code = pluginTransformResults.code;
2763
- if (isString$1(pluginTransformResults.id)) transformResults.id = pluginTransformResults.id;
2764
- /**
2765
- * add dependencies from plugin transform results, e.g. transformed sass files
2766
- */
2767
- transformResults.dependencies.push(...getDependencySubset(pluginTransformResults.dependencies, transformResults.dependencies));
2814
+ if (pluginTransformResults != null) {
2815
+ if (isString$1(pluginTransformResults)) transformResults.code = pluginTransformResults;
2816
+ else {
2817
+ if (isString$1(pluginTransformResults.code)) transformResults.code = pluginTransformResults.code;
2818
+ if (isString$1(pluginTransformResults.id)) transformResults.id = pluginTransformResults.id;
2819
+ /**
2820
+ * add dependencies from plugin transform results, e.g. transformed sass files
2821
+ */
2822
+ transformResults.dependencies.push(...getDependencySubset(pluginTransformResults.dependencies, transformResults.dependencies));
2823
+ }
2768
2824
  }
2769
2825
  }
2770
2826
  } catch (e) {
2771
2827
  catchError(buildCtx.diagnostics, e);
2772
2828
  }
2773
2829
  buildCtx.diagnostics.push(...pluginCtx.diagnostics);
2774
- if (!isRawCssFile) if (shouldParseCssDocs && cmp != null) {
2775
- cmp.styleDocs = cmp.styleDocs || [];
2776
- const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, transformResults.id, transformResults.code, cmp.styleDocs);
2777
- transformResults.code = cssParseResults.styleText;
2778
- transformResults.dependencies.push(...getDependencySubset(cssParseResults.imports, transformResults.dependencies));
2779
- } else {
2780
- const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, transformResults.id, transformResults.code);
2781
- transformResults.code = cssParseResults.styleText;
2782
- transformResults.dependencies.push(...getDependencySubset(cssParseResults.imports, transformResults.dependencies));
2830
+ if (!isRawCssFile) {
2831
+ if (shouldParseCssDocs && cmp != null) {
2832
+ cmp.styleDocs = cmp.styleDocs || [];
2833
+ const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, transformResults.id, transformResults.code, cmp.styleDocs);
2834
+ transformResults.code = cssParseResults.styleText;
2835
+ transformResults.dependencies.push(...getDependencySubset(cssParseResults.imports, transformResults.dependencies));
2836
+ } else {
2837
+ const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, transformResults.id, transformResults.code);
2838
+ transformResults.code = cssParseResults.styleText;
2839
+ transformResults.dependencies.push(...getDependencySubset(cssParseResults.imports, transformResults.dependencies));
2840
+ }
2783
2841
  }
2784
2842
  return transformResults;
2785
2843
  };
@@ -2810,13 +2868,15 @@ const runPluginTransformsEsmImports = async (config, compilerCtx, buildCtx, code
2810
2868
  if (results != null) {
2811
2869
  if (isFunction(results.then)) pluginTransformResults = await results;
2812
2870
  else pluginTransformResults = results;
2813
- if (pluginTransformResults != null) if (isString$1(pluginTransformResults)) transformResults.code = pluginTransformResults;
2814
- else {
2815
- if (isString$1(pluginTransformResults.code)) transformResults.code = pluginTransformResults.code;
2816
- if (isString$1(pluginTransformResults.id)) transformResults.id = pluginTransformResults.id;
2817
- if (Array.isArray(pluginTransformResults.dependencies)) {
2818
- const imports = pluginTransformResults.dependencies.filter((f) => !transformResults.dependencies.includes(f));
2819
- transformResults.dependencies.push(...imports);
2871
+ if (pluginTransformResults != null) {
2872
+ if (isString$1(pluginTransformResults)) transformResults.code = pluginTransformResults;
2873
+ else {
2874
+ if (isString$1(pluginTransformResults.code)) transformResults.code = pluginTransformResults.code;
2875
+ if (isString$1(pluginTransformResults.id)) transformResults.id = pluginTransformResults.id;
2876
+ if (Array.isArray(pluginTransformResults.dependencies)) {
2877
+ const imports = pluginTransformResults.dependencies.filter((f) => !transformResults.dependencies.includes(f));
2878
+ transformResults.dependencies.push(...imports);
2879
+ }
2820
2880
  }
2821
2881
  }
2822
2882
  }
@@ -2862,8 +2922,8 @@ const optimizeCss$1 = async (config, compilerCtx, diagnostics, styleText, filePa
2862
2922
  };
2863
2923
  //#endregion
2864
2924
  //#region src/compiler/style/component-global-styles.ts
2865
- const STENCIL_GLOBALS_RE = /@import\s+(?:url\()?\s*['"]stencil-globals['"]\s*\)?\s*;?/g;
2866
- const STENCIL_HYDRATE_RE = /@import\s+(?:url\()?\s*['"]stencil-hydrate['"]\s*\)?\s*;?/g;
2925
+ const STENCIL_GLOBALS_RE = /@import\s+(?:url\()?\s*['"]stencil-globals['"]\s*\)?([^;]*);?/g;
2926
+ const STENCIL_HYDRATE_RE = /@import\s+(?:url\()?\s*['"]stencil-hydrate['"]\s*\)?([^;]*);?/g;
2867
2927
  const hasStencilGlobalsImport = (css) => css.includes("stencil-globals");
2868
2928
  const hasStencilHydrateImport = (css) => css.includes("stencil-hydrate");
2869
2929
  /**
@@ -2886,12 +2946,16 @@ const generateHydrateCss = (config, buildCtx) => {
2886
2946
  };
2887
2947
  /**
2888
2948
  * Replace `@import "stencil-hydrate"` in CSS with the generated FOUC-prevention styles.
2949
+ * Supports trailing `layer()`/`supports()`/media modifiers, e.g. `@import "stencil-hydrate" layer(init);`.
2889
2950
  * @param css the CSS string to process
2890
2951
  * @param config the Stencil configuration
2891
2952
  * @param buildCtx the current build context, used to get the list of components in the build
2892
2953
  * @returns the CSS string with `@import "stencil-hydrate"` replaced by generated styles
2893
2954
  */
2894
- const resolveStencilHydrateImport = (css, config, buildCtx) => css.replace(STENCIL_HYDRATE_RE, generateHydrateCss(config, buildCtx));
2955
+ const resolveStencilHydrateImport = (css, config, buildCtx) => {
2956
+ const hydrateCss = generateHydrateCss(config, buildCtx);
2957
+ return css.replace(STENCIL_HYDRATE_RE, (_match, modifiers) => wrapCssWithImportModifiers(hydrateCss, modifiers));
2958
+ };
2895
2959
  /**
2896
2960
  * Collect and build all component-level globalStyle/globalStyleUrl CSS from the current build.
2897
2961
  * Results are cached per file path via the existing globalStyleCache.
@@ -2929,6 +2993,7 @@ const collectAndBuildComponentGlobalStyles = async (config, compilerCtx, buildCt
2929
2993
  * Replace `@import "stencil-globals"` in CSS with the collected component global styles.
2930
2994
  * Also registers component global style files as cssModuleImports of the global stylesheet
2931
2995
  * so the build cache is properly invalidated when those files change.
2996
+ * Supports trailing `layer()`/`supports()`/media modifiers, e.g. `@import "stencil-globals" layer(init);`.
2932
2997
  *
2933
2998
  * @param css the CSS string to process
2934
2999
  * @param config the Stencil configuration
@@ -2945,7 +3010,7 @@ const resolveStencilGlobalsImport = async (css, config, compilerCtx, buildCtx, g
2945
3010
  for (const p of filePaths) if (!existing.includes(p)) existing.push(p);
2946
3011
  compilerCtx.cssModuleImports.set(globalStyleInputPath, existing);
2947
3012
  }
2948
- return css.replace(STENCIL_GLOBALS_RE, collectedCss);
3013
+ return css.replace(STENCIL_GLOBALS_RE, (_match, modifiers) => wrapCssWithImportModifiers(collectedCss, modifiers));
2949
3014
  };
2950
3015
  //#endregion
2951
3016
  //#region src/compiler/style/global-styles.ts
@@ -3466,7 +3531,8 @@ const getStencilInternalModule = (config, compilerExe, internalModule) => {
3466
3531
  moduleId: "@stencil/core",
3467
3532
  path: "runtime/" + internalModule
3468
3533
  }));
3469
- return normalizePath(join$2(dirname$1(compilerExe), "..", "runtime", internalModule));
3534
+ const compilerExeDir = dirname$1(compilerExe);
3535
+ return normalizePath(join$2(compilerExeDir, "..", "runtime", internalModule));
3470
3536
  };
3471
3537
  const getHydratedFlagHead = (h) => {
3472
3538
  let initial;
@@ -3518,7 +3584,8 @@ const getPackageJsonPath = (resolvedPath, importee) => {
3518
3584
  for (let i = 0; i < 10; i++) {
3519
3585
  currentPath = dirname$1(currentPath);
3520
3586
  const aBasename = basename$1(currentPath);
3521
- const bBasename = basename$1(dirname$1(currentPath));
3587
+ const upDir = dirname$1(currentPath);
3588
+ const bBasename = basename$1(upDir);
3522
3589
  if (aBasename === importee && bBasename === "node_modules") return join$2(currentPath, "package.json");
3523
3590
  }
3524
3591
  return null;
@@ -3567,7 +3634,7 @@ const FORMAT_TEXT_EXTS = [
3567
3634
  "vert"
3568
3635
  ];
3569
3636
  const FORMAT_URL_MIME = { svg: "image/svg+xml" };
3570
- const DATAURL_MAX_IMAGE_SIZE = 4 * 1024;
3637
+ const DATAURL_MAX_IMAGE_SIZE = 4096;
3571
3638
  const formatText = (code, filePath) => {
3572
3639
  const varName = createJsVarName(basename$1(filePath));
3573
3640
  return `const ${varName} = ${JSON.stringify(code)};export default ${varName};`;
@@ -3665,6 +3732,7 @@ const parseImportPath = (importPath) => {
3665
3732
  encapsulation: urlParams.get("encapsulation") || "none",
3666
3733
  mode: urlParams.get("mode") || "$"
3667
3734
  };
3735
+ else if (urlParams.has("stencil") && parsedPath.basename.endsWith(".css")) parsedPath.data = { encapsulation: "none" };
3668
3736
  } else if (parsedPath.basename.endsWith(".css")) parsedPath.data = { encapsulation: "none" };
3669
3737
  }
3670
3738
  return parsedPath;
@@ -3904,7 +3972,7 @@ const loaderPlugin = (entries = {}) => {
3904
3972
  };
3905
3973
  //#endregion
3906
3974
  //#region src/compiler/bundle/plugin-helper.ts
3907
- const builtIns = new Set([
3975
+ const builtIns = /* @__PURE__ */ new Set([
3908
3976
  "child_process",
3909
3977
  "cluster",
3910
3978
  "dgram",
@@ -4061,6 +4129,7 @@ const createModule = (staticSourceFile, staticSourceFileText, emitFilepath) => (
4061
4129
  hasSignalsImport: false,
4062
4130
  htmlAttrNames: [],
4063
4131
  htmlParts: [],
4132
+ htmlSlots: [],
4064
4133
  htmlTagNames: [],
4065
4134
  isCollectionDependency: false,
4066
4135
  isLegacy: false,
@@ -4098,7 +4167,8 @@ const typescriptPlugin = (compilerCtx, bundleOpts, config) => {
4098
4167
  */
4099
4168
  load(id) {
4100
4169
  if (isAbsolute$1(id)) {
4101
- const module = getModule(compilerCtx, normalizeFsPath(id));
4170
+ const fsFilePath = normalizeFsPath(id);
4171
+ const module = getModule(compilerCtx, fsFilePath);
4102
4172
  if (module) {
4103
4173
  if (!module.sourceMapFileText) return {
4104
4174
  code: module.staticSourceFileText,
@@ -4280,7 +4350,7 @@ const loadMinifyJsDiagnostics = (sourceText, diagnostics, error) => {
4280
4350
  }
4281
4351
  diagnostics.push(d);
4282
4352
  };
4283
- const MINIFY_CHAR_BREAK = new Set([
4353
+ const MINIFY_CHAR_BREAK = /* @__PURE__ */ new Set([
4284
4354
  " ",
4285
4355
  "=",
4286
4356
  ".",
@@ -4502,16 +4572,18 @@ const workerPlugin = (config, compilerCtx, buildCtx, platform, inlineWorkers) =>
4502
4572
  const workerEntryPath = getWorkerEntryPath(id);
4503
4573
  if (workerEntryPath != null) {
4504
4574
  const worker = await getWorker(config, compilerCtx, buildCtx, this, workersMap, workerEntryPath);
4505
- if (worker) if (inlineWorkers) return {
4506
- code: getInlineWorkerProxy(workerEntryPath, worker.workerMsgId, worker.exports),
4507
- map: { mappings: "" },
4508
- moduleSideEffects: false
4509
- };
4510
- else return {
4511
- code: getWorkerProxy(workerEntryPath, worker.exports),
4512
- map: { mappings: "" },
4513
- moduleSideEffects: false
4514
- };
4575
+ if (worker) {
4576
+ if (inlineWorkers) return {
4577
+ code: getInlineWorkerProxy(workerEntryPath, worker.workerMsgId, worker.exports),
4578
+ map: { mappings: "" },
4579
+ moduleSideEffects: false
4580
+ };
4581
+ else return {
4582
+ code: getWorkerProxy(workerEntryPath, worker.exports),
4583
+ map: { mappings: "" },
4584
+ moduleSideEffects: false
4585
+ };
4586
+ }
4515
4587
  }
4516
4588
  return null;
4517
4589
  }
@@ -4810,7 +4882,8 @@ ${exportedMethods.map((exportedMethod) => {
4810
4882
  //#region src/compiler/bundle/bundle-output.ts
4811
4883
  const bundleOutput = async (config, compilerCtx, buildCtx, bundleOpts) => {
4812
4884
  try {
4813
- return await rolldown(getRolldownOptions(config, compilerCtx, buildCtx, bundleOpts));
4885
+ const rolldownOptions = getRolldownOptions(config, compilerCtx, buildCtx, bundleOpts);
4886
+ return await rolldown(rolldownOptions);
4814
4887
  } catch (e) {
4815
4888
  if (!buildCtx.hasError && isRolldownError(e)) loadRolldownDiagnostics(config, compilerCtx, buildCtx, e);
4816
4889
  }
@@ -5435,13 +5508,14 @@ const updateCjsStyleRequires = (transformOpts, tsSourceFile, moduleFile) => {
5435
5508
  return tsSourceFile;
5436
5509
  };
5437
5510
  const getStyleImportPath = (transformOpts, tsSourceFile, cmp, style, importPath) => {
5438
- return serializeImportPath({
5511
+ const importData = {
5439
5512
  importeePath: importPath,
5440
5513
  importerPath: tsSourceFile.fileName,
5441
5514
  tag: cmp.tagName,
5442
5515
  encapsulation: cmp.encapsulation,
5443
5516
  mode: style.modeName
5444
- }, transformOpts.styleImportData);
5517
+ };
5518
+ return serializeImportPath(importData, transformOpts.styleImportData);
5445
5519
  };
5446
5520
  //#endregion
5447
5521
  //#region src/compiler/transformers/add-static-style.ts
@@ -5481,8 +5555,10 @@ const addStaticStylePropertyToClass = (styleStatements, cmp, buildCtx) => {
5481
5555
  }
5482
5556
  };
5483
5557
  const getStyleLiteral = (cmp, buildCtx) => {
5484
- if (Array.isArray(cmp.styles) && cmp.styles.length > 0) if (cmp.styles.length > 1 || cmp.styles.length === 1 && cmp.styles[0].modeName !== "$") return getMultipleModeStyle(cmp, cmp.styles, buildCtx);
5485
- else return getSingleStyle(cmp, cmp.styles[0], buildCtx);
5558
+ if (Array.isArray(cmp.styles) && cmp.styles.length > 0) {
5559
+ if (cmp.styles.length > 1 || cmp.styles.length === 1 && cmp.styles[0].modeName !== "$") return getMultipleModeStyle(cmp, cmp.styles, buildCtx);
5560
+ else return getSingleStyle(cmp, cmp.styles[0], buildCtx);
5561
+ }
5486
5562
  return null;
5487
5563
  };
5488
5564
  const getMultipleModeStyle = (cmp, styles, buildCtx) => {
@@ -5904,30 +5980,31 @@ const updateStencilCoreImports = (updatedCoreImportPath) => {
5904
5980
  /**
5905
5981
  * A set of imports which we don't want to remove from an output file
5906
5982
  */
5907
- const KEEP_IMPORTS = new Set([
5908
- "h",
5909
- "setMode",
5910
- "getMode",
5911
- "setPlatformHelpers",
5983
+ const KEEP_IMPORTS = /* @__PURE__ */ new Set([
5912
5984
  "Build",
5913
5985
  "Env",
5914
- "Host",
5915
5986
  "Fragment",
5987
+ "Host",
5988
+ "Mixin",
5989
+ "ReactiveControllerHost",
5990
+ "forceUpdate",
5991
+ "forceModeUpdate",
5916
5992
  "getAssetPath",
5917
- "writeTask",
5918
- "readTask",
5919
5993
  "getElement",
5920
- "getShadowRoot",
5921
- "forceUpdate",
5994
+ "getMode",
5922
5995
  "getRenderingRef",
5923
- "forceModeUpdate",
5996
+ "getShadowRoot",
5997
+ "h",
5998
+ "jsx",
5999
+ "jsxs",
6000
+ "readTask",
6001
+ "render",
5924
6002
  "setErrorHandler",
6003
+ "setMode",
6004
+ "setPlatformHelpers",
5925
6005
  "setTagTransformer",
5926
6006
  "transformTag",
5927
- "Mixin",
5928
- "jsx",
5929
- "jsxs",
5930
- "render"
6007
+ "writeTask"
5931
6008
  ]);
5932
6009
  //#endregion
5933
6010
  //#region src/compiler/app-core/bundle-app-core.ts
@@ -6111,7 +6188,8 @@ const writeLazyChunk = async (config, compilerCtx, buildCtx, rolldownResult, out
6111
6188
  };
6112
6189
  const writeLazyEntry = async (config, compilerCtx, buildCtx, rolldownResult, outputTargetType, destinations, lazyRuntimeData, sourceTarget, shouldMinify, isBrowserBuild) => {
6113
6190
  if (isBrowserBuild && ["loader"].includes(rolldownResult.entryKey)) return;
6114
- const { code, sourceMap } = await convertChunk(config, compilerCtx, buildCtx, sourceTarget, shouldMinify, false, isBrowserBuild, rolldownResult.code.replace(`["__STENCIL_LAZY_DATA__"]`, `${lazyRuntimeData}`), rolldownResult.map);
6191
+ const inputCode = rolldownResult.code.replace(`["__STENCIL_LAZY_DATA__"]`, `${lazyRuntimeData}`);
6192
+ const { code, sourceMap } = await convertChunk(config, compilerCtx, buildCtx, sourceTarget, shouldMinify, false, isBrowserBuild, inputCode, rolldownResult.map);
6115
6193
  await Promise.all(destinations.map((dst) => {
6116
6194
  const filePath = join$2(dst, rolldownResult.fileName);
6117
6195
  let fileCode = code;
@@ -6131,7 +6209,8 @@ const writeLazyEntry = async (config, compilerCtx, buildCtx, rolldownResult, out
6131
6209
  * @returns A stringified representation of the lazy bundles.
6132
6210
  */
6133
6211
  const formatLazyBundlesRuntimeMeta = (bundleModules) => {
6134
- return stringifyRuntimeData(bundleModules.slice().sort(sortBundleModules).map(formatLazyRuntimeBundle));
6212
+ const lazyBundles = bundleModules.slice().sort(sortBundleModules).map(formatLazyRuntimeBundle);
6213
+ return stringifyRuntimeData(lazyBundles);
6135
6214
  };
6136
6215
  /**
6137
6216
  * Formats a bundle module into a tuple of bundle ID and component metadata for use at runtime.
@@ -6307,7 +6386,8 @@ const generateCjs = async (config, compilerCtx, buildCtx, rolldownBuild, outputT
6307
6386
  if (config.compat.enableImportInjection) esmOpts.dynamicImportInCjs = false;
6308
6387
  const results = await generateRolldownOutput(rolldownBuild, esmOpts, config, buildCtx.entryModules);
6309
6388
  if (results != null) {
6310
- buildCtx.commonJsComponentBundle = await generateLazyModules(config, compilerCtx, buildCtx, outputTargetType, cjsOutputs.map((o) => o.cjsDir).filter((cjsDir) => typeof cjsDir === "string"), results, "es2017", false);
6389
+ const destinations = cjsOutputs.map((o) => o.cjsDir).filter((cjsDir) => typeof cjsDir === "string");
6390
+ buildCtx.commonJsComponentBundle = await generateLazyModules(config, compilerCtx, buildCtx, outputTargetType, destinations, results, "es2017", false);
6311
6391
  await generateShortcuts$1(compilerCtx, results, cjsOutputs);
6312
6392
  }
6313
6393
  }
@@ -6342,7 +6422,8 @@ const generateEsm = async (config, compilerCtx, buildCtx, rolldownBuild, outputT
6342
6422
  const outputTargetType = esmOutputs[0].type;
6343
6423
  const output = await generateRolldownOutput(rolldownBuild, esmOpts, config, buildCtx.entryModules);
6344
6424
  if (output != null) {
6345
- buildCtx.esmComponentBundle = await generateLazyModules(config, compilerCtx, buildCtx, outputTargetType, esmOutputs.map((o) => o.esmDir).filter((esmDir) => typeof esmDir === "string"), output, "es2017", false);
6425
+ const es2017destinations = esmOutputs.map((o) => o.esmDir).filter((esmDir) => typeof esmDir === "string");
6426
+ buildCtx.esmComponentBundle = await generateLazyModules(config, compilerCtx, buildCtx, outputTargetType, es2017destinations, output, "es2017", false);
6346
6427
  await generateShortcuts(compilerCtx, outputTargets, output);
6347
6428
  }
6348
6429
  }
@@ -6367,7 +6448,7 @@ const generateEsmBrowser = async (config, compilerCtx, buildCtx, rolldownBuild,
6367
6448
  const esmOutputs = outputTargets.filter((o) => !!o.esmDir && !!o.isBrowserBuild);
6368
6449
  if (esmOutputs.length) {
6369
6450
  const outputTargetType = esmOutputs[0].type;
6370
- const output = await generateRolldownOutput(rolldownBuild, {
6451
+ const esmOpts = {
6371
6452
  banner: generatePreamble(config),
6372
6453
  format: "es",
6373
6454
  entryFileNames: "[name].js",
@@ -6375,7 +6456,8 @@ const generateEsmBrowser = async (config, compilerCtx, buildCtx, rolldownBuild,
6375
6456
  assetFileNames: esmOutputs[0].hashFileNames ? "p-[hash][extname]" : "[name]-[hash][extname]",
6376
6457
  sourcemap: config.sourceMap,
6377
6458
  plugins: [lazyBundleIdPlugin(buildCtx, config, esmOutputs[0].hashFileNames ?? true, esmOutputs[0].hashedFileNameLength ?? 8, "", true)]
6378
- }, config, buildCtx.entryModules);
6459
+ };
6460
+ const output = await generateRolldownOutput(rolldownBuild, esmOpts, config, buildCtx.entryModules);
6379
6461
  if (output != null) {
6380
6462
  const es2017destinations = esmOutputs.map((o) => o.esmDir).filter((esmDir) => typeof esmDir === "string");
6381
6463
  buildCtx.esmBrowserComponentBundle = await generateLazyModules(config, compilerCtx, buildCtx, outputTargetType, es2017destinations, output, "es2017", true);
@@ -6418,15 +6500,18 @@ const generateLoader = async (compilerCtx, outputTargets) => {
6418
6500
  await Promise.all(outputTargets.map(async (o) => {
6419
6501
  if (!o.loaderDir || !o.esmDir || !o.typesDir) return;
6420
6502
  const loaderIndexJs = join$2(o.loaderDir, "index.js");
6421
- const relativeEsmLoader = relativeImport(loaderIndexJs, join$2(o.esmDir, "loader.js"));
6503
+ const esmLoaderPath = join$2(o.esmDir, "loader.js");
6504
+ const relativeEsmLoader = relativeImport(loaderIndexJs, esmLoaderPath);
6422
6505
  await compilerCtx.fs.writeFile(loaderIndexJs, `export * from '${relativeEsmLoader}';\n`, { outputTargetType: o.type });
6423
6506
  if (o.cjsDir) {
6424
6507
  const loaderIndexCjs = join$2(o.loaderDir, "index.cjs");
6425
- const relativeCjsLoader = relativeImport(loaderIndexCjs, join$2(o.cjsDir, "loader.cjs"));
6508
+ const cjsLoaderPath = join$2(o.cjsDir, "loader.cjs");
6509
+ const relativeCjsLoader = relativeImport(loaderIndexCjs, cjsLoaderPath);
6426
6510
  await compilerCtx.fs.writeFile(loaderIndexCjs, `module.exports = require('${relativeCjsLoader}');\n`, { outputTargetType: o.type });
6427
6511
  }
6428
6512
  const loaderIndexDts = join$2(o.loaderDir, "index.d.ts");
6429
- const relativeDtsPath = relativeImport(loaderIndexDts, join$2(o.typesDir, "loader.d.ts"));
6513
+ const loaderDtsPath = join$2(o.typesDir, "loader.d.ts");
6514
+ const relativeDtsPath = relativeImport(loaderIndexDts, loaderDtsPath);
6430
6515
  await compilerCtx.fs.writeFile(loaderIndexDts, `export * from '${relativeDtsPath}';\n`, { outputTargetType: o.type });
6431
6516
  }));
6432
6517
  };
@@ -6649,7 +6734,8 @@ const canSkipAssetsCopy = (compilerCtx, entryModules, filesChanged) => {
6649
6734
  entryModules.forEach((entryModule) => {
6650
6735
  entryModule.cmps.forEach((cmp) => {
6651
6736
  if (cmp.assetsDirs != null) cmp.assetsDirs.forEach((assetsDir) => {
6652
- if (changedFileDirPath === normalizePath(assetsDir.absolutePath)) {
6737
+ const assetDirPath = normalizePath(assetsDir.absolutePath);
6738
+ if (changedFileDirPath === assetDirPath) {
6653
6739
  shouldSkipAssetsCopy = false;
6654
6740
  return;
6655
6741
  }
@@ -6685,7 +6771,8 @@ const outputAssets = async (config, compilerCtx, buildCtx) => {
6685
6771
  allCopyTasks.push(...copyTasks);
6686
6772
  }
6687
6773
  for (const wwwTarget of wwwTargets) {
6688
- const copyTasks = getComponentAssetsCopyTasks(config, buildCtx, join$2(wwwTarget.buildDir, "assets"), false);
6774
+ const wwwAssetsDir = join$2(wwwTarget.buildDir, "assets");
6775
+ const copyTasks = getComponentAssetsCopyTasks(config, buildCtx, wwwAssetsDir, false);
6689
6776
  allCopyTasks.push(...copyTasks);
6690
6777
  }
6691
6778
  if (allCopyTasks.length > 0) {
@@ -6914,6 +7001,7 @@ const generateDocData = async (config, compilerCtx, buildCtx) => {
6914
7001
  typescriptVersion: versions.typescript
6915
7002
  },
6916
7003
  components: await getDocsComponents(config, compilerCtx, buildCtx),
7004
+ usage: await generateUsages(compilerCtx, normalizePath(join$2(config.srcDir, "usage"))),
6917
7005
  typeLibrary
6918
7006
  };
6919
7007
  };
@@ -6936,7 +7024,7 @@ function findSupplementalPublicTypes(outputTargets) {
6936
7024
  * @returns the derived metadata
6937
7025
  */
6938
7026
  const getDocsComponents = async (config, compilerCtx, buildCtx) => {
6939
- return sortBy(flatOne(await Promise.all(buildCtx.moduleFiles.map(async (moduleFile) => {
7027
+ const results = await Promise.all(buildCtx.moduleFiles.map(async (moduleFile) => {
6940
7028
  const filePath = moduleFile.sourceFilePath;
6941
7029
  const dirPath = normalizePath(dirname$1(filePath));
6942
7030
  const readmePath = normalizePath(join$2(dirPath, "readme.md"));
@@ -6964,12 +7052,13 @@ const getDocsComponents = async (config, compilerCtx, buildCtx) => {
6964
7052
  methods: getDocsMethods(cmp.methods),
6965
7053
  events: getDocsEvents(cmp.events),
6966
7054
  styles: getDocsStyles(cmp),
6967
- slots: getDocsSlots(cmp.docs.tags),
7055
+ slots: getDocsSlots(cmp.htmlSlots, cmp.docs.tags),
6968
7056
  parts: getDocsParts(cmp.htmlParts, cmp.docs.tags),
6969
7057
  customStates: getDocsCustomStates(cmp),
6970
7058
  listeners: getDocsListeners(cmp.listeners)
6971
7059
  }));
6972
- }))), (cmp) => cmp.tag);
7060
+ }));
7061
+ return sortBy(flatOne(results), (cmp) => cmp.tag);
6973
7062
  };
6974
7063
  const buildDocsDepGraph = (cmp, cmps) => {
6975
7064
  const dependencies = {};
@@ -7156,11 +7245,17 @@ const getDocsDeprecationText = (tags) => {
7156
7245
  const deprecation = tags.find((t) => t.name === "deprecated");
7157
7246
  if (deprecation) return deprecation.text || "";
7158
7247
  };
7159
- const getDocsSlots = (tags) => {
7160
- return sortBy(getNameText("slot", tags).map(([name, docs]) => ({
7248
+ const DEFAULT_SLOT_DOCS = "The default slot";
7249
+ const getDocsSlots = (vdom, tags) => {
7250
+ const docsSlots = getNameText("slot", tags).map(([name, docs]) => ({
7161
7251
  name,
7162
7252
  docs
7163
- })), (a) => a.name);
7253
+ }));
7254
+ const vdomSlots = vdom.map((name) => ({
7255
+ name,
7256
+ docs: name === "" ? DEFAULT_SLOT_DOCS : ""
7257
+ }));
7258
+ return sortBy(unique([...docsSlots, ...vdomSlots], (s) => s.name), (a) => a.name);
7164
7259
  };
7165
7260
  const getDocsParts = (vdom, tags) => {
7166
7261
  const docsParts = getNameText("part", tags).map(([name, docs]) => ({
@@ -7226,7 +7321,7 @@ const cmpMetaToDocsComponent = (cmp, filePath, rootDir = process.cwd()) => {
7226
7321
  methods: getDocsMethods(cmp.methods ?? []),
7227
7322
  events: getDocsEvents(cmp.events ?? []),
7228
7323
  styles: getDocsStyles(cmp),
7229
- slots: getDocsSlots(docs.tags),
7324
+ slots: getDocsSlots(cmp.htmlSlots ?? [], docs.tags),
7230
7325
  parts: getDocsParts(cmp.htmlParts ?? [], docs.tags),
7231
7326
  customStates: getDocsCustomStates(cmp),
7232
7327
  listeners: getDocsListeners(cmp.listeners ?? [])
@@ -7335,64 +7430,553 @@ const outputCustom = async (config, compilerCtx, buildCtx) => {
7335
7430
  }));
7336
7431
  };
7337
7432
  //#endregion
7338
- //#region src/compiler/docs/cem/index.ts
7339
- /**
7340
- * Generate Custom Elements Manifest (custom-elements.json) output
7341
- * conforming to the Custom Elements Manifest specification.
7342
- * @see https://github.com/webcomponents/custom-elements-manifest
7343
- *
7344
- * @param compilerCtx the current compiler context
7345
- * @param docsData the generated docs data from Stencil components
7346
- * @param outputTargets the output targets configured for the build
7347
- */
7348
- const generateCustomElementsManifestDocs = async (compilerCtx, docsData, outputTargets) => {
7349
- const cemOutputTargets = outputTargets.filter(isOutputTargetDocsCustomElementsManifest);
7350
- if (cemOutputTargets.length === 0) return;
7351
- const manifest = generateManifest(docsData);
7352
- const jsonContent = JSON.stringify(manifest, null, 2);
7353
- await Promise.all(cemOutputTargets.map((outputTarget) => compilerCtx.fs.writeFile(outputTarget.file, jsonContent)));
7433
+ //#region src/compiler/docs/readme/markdown-usage.ts
7434
+ const usageToMarkdown = (usages) => {
7435
+ const content = [];
7436
+ const merged = mergeUsages(usages);
7437
+ if (merged.length === 0) return content;
7438
+ content.push(`## Usage`);
7439
+ merged.forEach(({ name, text }) => {
7440
+ content.push("");
7441
+ content.push(`### ${toTitleCase(name)}`);
7442
+ content.push("");
7443
+ content.push(text);
7444
+ content.push("");
7445
+ });
7446
+ content.push("");
7447
+ content.push("");
7448
+ return content;
7354
7449
  };
7355
- /**
7356
- * Generate the Custom Elements Manifest from Stencil docs data
7357
- * @param docsData the generated docs data
7358
- * @returns the Custom Elements Manifest object
7359
- */
7360
- const generateManifest = (docsData) => {
7361
- const componentsByFile = /* @__PURE__ */ new Map();
7362
- for (const component of docsData.components) {
7363
- const filePath = component.filePath;
7364
- if (!componentsByFile.has(filePath)) componentsByFile.set(filePath, []);
7365
- componentsByFile.get(filePath).push(component);
7450
+ const mergeUsages = (usages) => {
7451
+ const keys = Object.keys(usages);
7452
+ const map = /* @__PURE__ */ new Map();
7453
+ keys.forEach((key) => {
7454
+ const usage = usages[key].trim();
7455
+ const array = map.get(usage) || [];
7456
+ array.push(key);
7457
+ map.set(usage, array);
7458
+ });
7459
+ const merged = [];
7460
+ map.forEach((value, key) => {
7461
+ merged.push({
7462
+ name: value.join(" / "),
7463
+ text: key
7464
+ });
7465
+ });
7466
+ return merged;
7467
+ };
7468
+ //#endregion
7469
+ //#region src/compiler/docs/agent-skill/frontmatter.ts
7470
+ /**
7471
+ * Truncate a string to a max length, replacing any trailing content with an ellipsis.
7472
+ * @param text the text to truncate
7473
+ * @param maxLen the max length of the returned string
7474
+ * @returns the truncated string
7475
+ */
7476
+ const truncate = (text, maxLen) => text.length > maxLen ? `${text.slice(0, maxLen - 1).trimEnd()}…` : text;
7477
+ /**
7478
+ * Extract the first sentence from a block of text, for use as a short summary.
7479
+ * Bounded to the first paragraph (text up to a blank line) so a heading or
7480
+ * short first line doesn't get glued to unrelated content further down.
7481
+ * Falls back to the full (truncated) first paragraph if no sentence-ending
7482
+ * punctuation is found within it.
7483
+ * @param text the text to extract a summary from
7484
+ * @param maxLen the max length of the returned string
7485
+ * @returns the first sentence, or an empty string if `text` is empty
7486
+ */
7487
+ const firstSentence = (text, maxLen = 200) => {
7488
+ if (!text) return "";
7489
+ const trimmed = text.trim();
7490
+ if (trimmed === "") return "";
7491
+ const firstParagraph = trimmed.split(/\r?\n\s*\r?\n/)[0];
7492
+ const match = firstParagraph.match(/^[\s\S]*?[.!?](?=\s|$)/);
7493
+ const sentence = (match ? match[0] : firstParagraph).trim();
7494
+ return truncate(sentence, maxLen);
7495
+ };
7496
+ /**
7497
+ * Strip a single leading markdown ATX heading (e.g. `# Getting Started`), if
7498
+ * present, so summary extraction starts from the first real paragraph of prose.
7499
+ * @param text the text to strip a leading heading from
7500
+ * @returns the text with any leading heading removed
7501
+ */
7502
+ const stripLeadingHeading = (text) => text.replace(/^\s*#{1,6}[^\n]*\n+/, "");
7503
+ /**
7504
+ * Sanitize a string into a valid Agent Skill `name` (lowercase, alphanumeric + hyphens).
7505
+ * @param raw the raw string to sanitize, e.g. a project namespace
7506
+ * @returns the kebab-cased name, or 'skill' if `raw` sanitizes to an empty string
7507
+ */
7508
+ const toSkillName = (raw) => {
7509
+ return raw.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
7510
+ };
7511
+ /**
7512
+ * Auto-generate the skill's `description` when the user doesn't supply one -
7513
+ * prefers real project-level usage content (see `<srcDir>/usage/*.md`) over a
7514
+ * generic sentence built from the component tag list.
7515
+ * @param components the project's documented components
7516
+ * @param name the skill's (already-sanitized) name
7517
+ * @param projectUsage project-level usage content, from `JsonDocs.usage`
7518
+ * @returns the generated description
7519
+ */
7520
+ const buildSkillDescription = (components, name, projectUsage) => {
7521
+ if (projectUsage) {
7522
+ const firstEntry = Object.values(projectUsage)[0];
7523
+ const fromProjectUsage = firstEntry ? firstSentence(stripLeadingHeading(firstEntry), 400) : "";
7524
+ if (fromProjectUsage) return fromProjectUsage;
7525
+ }
7526
+ const tags = components.map((cmp) => cmp.tag);
7527
+ const description = `Use when building UI with the ${name} component library. Provides API reference and usage examples for its ${tags.length} component${tags.length === 1 ? "" : "s"}: ${tags.join(", ")}.`;
7528
+ return truncate(description, 800);
7529
+ };
7530
+ /**
7531
+ * Minimal YAML string serializer for the two flat frontmatter fields
7532
+ * (`name`/`description`). Quotes and escapes only when necessary - not a
7533
+ * general-purpose YAML writer.
7534
+ * @param value the string to serialize
7535
+ * @returns the value, quoted/escaped if it contains YAML-significant characters
7536
+ */
7537
+ const escapeYamlString = (value) => {
7538
+ if (!(value === "" || /[:#"'\n]/.test(value) || /^\s|\s$/.test(value) || /^[-?*&!|>%@`[\]{},]/.test(value))) return value;
7539
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\r\n|\r|\n/g, "\\n")}"`;
7540
+ };
7541
+ /**
7542
+ * Assemble the top-level `SKILL.md` content: frontmatter, project-level intro
7543
+ * (from `JsonDocs.usage`, if any), and an index of components linking to
7544
+ * their `components/<tag>.md` reference file.
7545
+ * @param docsData the project's generated docs data
7546
+ * @param outputTarget the (already-validated) docs-agent-skill output target
7547
+ * @returns the `SKILL.md` content
7548
+ */
7549
+ const generateSkillMarkdown = (docsData, outputTarget) => {
7550
+ const name = outputTarget.name;
7551
+ const description = outputTarget.description ?? buildSkillDescription(docsData.components, name, docsData.usage);
7552
+ const lines = [
7553
+ "---",
7554
+ `name: ${escapeYamlString(name)}`,
7555
+ `description: ${escapeYamlString(description)}`,
7556
+ "---",
7557
+ "",
7558
+ `# ${name}`,
7559
+ ""
7560
+ ];
7561
+ if (docsData.usage) lines.push(...usageToMarkdown(docsData.usage));
7562
+ lines.push("## Components", "");
7563
+ [...docsData.components].sort((a, b) => a.tag.localeCompare(b.tag)).forEach((cmp) => {
7564
+ const summary = firstSentence(cmp.overview);
7565
+ lines.push(`- [${cmp.tag}](components/${cmp.tag}.md)${summary ? ` — ${summary}` : ""}`);
7566
+ });
7567
+ lines.push("");
7568
+ return lines.join("\n");
7569
+ };
7570
+ //#endregion
7571
+ //#region src/compiler/docs/readme/docs-util.ts
7572
+ var MarkdownTable = class {
7573
+ rows = [];
7574
+ addHeader(data) {
7575
+ this.addRow(data, true);
7366
7576
  }
7367
- const modules = [];
7368
- for (const [filePath, components] of componentsByFile) {
7369
- const declarations = components.map((component) => componentToDeclaration(component));
7370
- const exports = components.flatMap((component) => {
7371
- const className = dashToPascalCase(component.tag);
7372
- return [{
7373
- kind: "js",
7374
- name: className,
7375
- declaration: { name: className }
7376
- }, {
7377
- kind: "custom-element-definition",
7378
- name: component.tag,
7379
- declaration: { name: className }
7380
- }];
7577
+ addRow(data, isHeader = false) {
7578
+ const colData = [];
7579
+ data.forEach((text) => {
7580
+ const col = {
7581
+ text: escapeMarkdownTableColumn(text),
7582
+ width: text.length
7583
+ };
7584
+ colData.push(col);
7381
7585
  });
7382
- modules.push({
7383
- kind: "javascript-module",
7384
- path: filePath,
7385
- declarations,
7386
- exports
7586
+ this.rows.push({
7587
+ columns: colData,
7588
+ isHeader
7387
7589
  });
7388
7590
  }
7389
- return {
7390
- schemaVersion: "2.1.0",
7391
- modules
7392
- };
7591
+ toMarkdown() {
7592
+ return createTable(this.rows);
7593
+ }
7393
7594
  };
7394
- /**
7395
- * Convert Stencil's ComponentCompilerTypeReferences to CEM TypeReference array
7595
+ const escapeMarkdownTableColumn = (text) => {
7596
+ text = text.replace(/\r?\n/g, " ");
7597
+ text = text.replace(/\|/g, "\\|");
7598
+ return text;
7599
+ };
7600
+ const createTable = (rows) => {
7601
+ const content = [];
7602
+ if (rows.length === 0) return content;
7603
+ normalizeColumCount(rows);
7604
+ normalizeColumnWidth(rows);
7605
+ const th = rows.find((r) => r.isHeader);
7606
+ if (th) {
7607
+ const headerRow = createRow(th);
7608
+ content.push(headerRow);
7609
+ content.push(createBorder(th));
7610
+ }
7611
+ rows.filter((r) => !r.isHeader).forEach((td) => {
7612
+ content.push(createRow(td));
7613
+ });
7614
+ return content;
7615
+ };
7616
+ const createBorder = (th) => {
7617
+ const border = {
7618
+ columns: [],
7619
+ isHeader: false
7620
+ };
7621
+ th.columns.forEach((c) => {
7622
+ const borderCol = {
7623
+ text: "",
7624
+ width: c.width
7625
+ };
7626
+ while (borderCol.text.length < borderCol.width) borderCol.text += "-";
7627
+ border.columns.push(borderCol);
7628
+ });
7629
+ return createRow(border);
7630
+ };
7631
+ const createRow = (row) => {
7632
+ const content = ["| "];
7633
+ row.columns.forEach((c) => {
7634
+ content.push(c.text);
7635
+ content.push(" | ");
7636
+ });
7637
+ return content.join("").trim();
7638
+ };
7639
+ const normalizeColumCount = (rows) => {
7640
+ let columnCount = 0;
7641
+ rows.forEach((r) => {
7642
+ if (r.columns.length > columnCount) columnCount = r.columns.length;
7643
+ });
7644
+ rows.forEach((r) => {
7645
+ while (r.columns.length < columnCount) r.columns.push({
7646
+ text: ``,
7647
+ width: 0
7648
+ });
7649
+ });
7650
+ };
7651
+ const normalizeColumnWidth = (rows) => {
7652
+ const columnCount = rows[0].columns.length;
7653
+ for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) {
7654
+ let longestText = 0;
7655
+ rows.forEach((r) => {
7656
+ const col = r.columns[columnIndex];
7657
+ if (col.text.length > longestText) longestText = col.text.length;
7658
+ });
7659
+ rows.forEach((r) => {
7660
+ const col = r.columns[columnIndex];
7661
+ col.width = longestText;
7662
+ while (col.text.length < longestText) col.text += " ";
7663
+ });
7664
+ }
7665
+ };
7666
+ /**
7667
+ * Checks if a given string is a valid hexadecimal color representation.
7668
+ *
7669
+ * @param str - The string to be checked.
7670
+ * @returns `true` if the string is a valid hex color (e.g., '#FF00AA', '#f0f'), `false` otherwise.
7671
+ *
7672
+ * @example
7673
+ * isHexColor('#FF00AA'); // true
7674
+ * isHexColor('#f0f'); // true
7675
+ * isHexColor('#abcde'); // false (too many characters)
7676
+ * isHexColor('FF00AA'); // false (missing #)
7677
+ */
7678
+ const isHexColor = (str) => {
7679
+ return /^#([0-9A-Fa-f]{3}){1,2}$/.test(str);
7680
+ };
7681
+ //#endregion
7682
+ //#region src/compiler/docs/readme/markdown-css-props.ts
7683
+ const stylesToMarkdown = (styles) => {
7684
+ const content = [];
7685
+ if (styles.length === 0) return content;
7686
+ content.push(`## CSS Custom Properties`);
7687
+ content.push(``);
7688
+ const table = new MarkdownTable();
7689
+ table.addHeader(["Name", "Description"]);
7690
+ styles.forEach((style) => {
7691
+ table.addRow([`\`${style.name}\``, style.docs]);
7692
+ });
7693
+ content.push(...table.toMarkdown());
7694
+ content.push(``);
7695
+ content.push(``);
7696
+ return content;
7697
+ };
7698
+ //#endregion
7699
+ //#region src/compiler/docs/readme/markdown-events.ts
7700
+ const eventsToMarkdown = (events, cmp, customColumns = []) => {
7701
+ const content = [];
7702
+ if (events.length === 0) return content;
7703
+ content.push(`## Events`);
7704
+ content.push(``);
7705
+ const table = new MarkdownTable();
7706
+ table.addHeader([
7707
+ "Event",
7708
+ "Description",
7709
+ "Type",
7710
+ ...customColumns.map((c) => c.header)
7711
+ ]);
7712
+ events.forEach((ev) => {
7713
+ table.addRow([
7714
+ `\`${ev.event}\``,
7715
+ getDocsField$2(ev),
7716
+ `\`CustomEvent<${ev.detail}>\``,
7717
+ ...customColumns.map((c) => c.content(ev, cmp))
7718
+ ]);
7719
+ });
7720
+ content.push(...table.toMarkdown());
7721
+ content.push(``);
7722
+ content.push(``);
7723
+ return content;
7724
+ };
7725
+ const getDocsField$2 = (prop) => {
7726
+ return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
7727
+ };
7728
+ //#endregion
7729
+ //#region src/compiler/docs/readme/markdown-methods.ts
7730
+ const methodsToMarkdown = (methods) => {
7731
+ const content = [];
7732
+ if (methods.length === 0) return content;
7733
+ content.push(`## Methods`);
7734
+ content.push(``);
7735
+ methods.forEach((method) => {
7736
+ content.push(`### \`${method.signature}\``);
7737
+ content.push(``);
7738
+ content.push(getDocsField$1(method));
7739
+ content.push(``);
7740
+ if (method.parameters.length > 0) {
7741
+ const parmsTable = new MarkdownTable();
7742
+ parmsTable.addHeader([
7743
+ "Name",
7744
+ "Type",
7745
+ "Description"
7746
+ ]);
7747
+ method.parameters.forEach(({ name, type, docs }) => {
7748
+ parmsTable.addRow([
7749
+ "`" + name + "`",
7750
+ "`" + type + "`",
7751
+ docs
7752
+ ]);
7753
+ });
7754
+ content.push(`#### Parameters`);
7755
+ content.push(``);
7756
+ content.push(...parmsTable.toMarkdown());
7757
+ content.push(``);
7758
+ }
7759
+ if (method.returns) {
7760
+ content.push(`#### Returns`);
7761
+ content.push(``);
7762
+ content.push(`Type: \`${method.returns.type}\``);
7763
+ content.push(``);
7764
+ content.push(method.returns.docs);
7765
+ content.push(``);
7766
+ }
7767
+ });
7768
+ content.push(``);
7769
+ return content;
7770
+ };
7771
+ const getDocsField$1 = (prop) => {
7772
+ return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
7773
+ };
7774
+ //#endregion
7775
+ //#region src/compiler/docs/readme/markdown-overview.ts
7776
+ /**
7777
+ * Generate an 'Overview' section for a markdown file
7778
+ * @param overview a component-level comment string to place in a markdown file
7779
+ * @returns The generated Overview section. If the provided overview is empty, return an empty list
7780
+ */
7781
+ const overviewToMarkdown = (overview) => {
7782
+ if (!overview) return [];
7783
+ const content = [];
7784
+ content.push(`## Overview`);
7785
+ content.push("");
7786
+ content.push(`${overview.trim()}`);
7787
+ content.push("");
7788
+ return content;
7789
+ };
7790
+ //#endregion
7791
+ //#region src/compiler/docs/readme/markdown-parts.ts
7792
+ /**
7793
+ * Converts a list of Shadow Parts metadata to a table written in Markdown
7794
+ * @param parts the Shadow parts metadata to convert
7795
+ * @returns a list of strings that make up the Markdown table
7796
+ */
7797
+ const partsToMarkdown = (parts) => {
7798
+ const content = [];
7799
+ if (parts.length === 0) return content;
7800
+ content.push(`## Shadow Parts`);
7801
+ content.push(``);
7802
+ const table = new MarkdownTable();
7803
+ table.addHeader(["Part", "Description"]);
7804
+ parts.forEach((style) => {
7805
+ table.addRow([style.name === "" ? "" : `\`"${style.name}"\``, style.docs]);
7806
+ });
7807
+ content.push(...table.toMarkdown());
7808
+ content.push(``);
7809
+ content.push(``);
7810
+ return content;
7811
+ };
7812
+ //#endregion
7813
+ //#region src/compiler/docs/readme/markdown-props.ts
7814
+ const propsToMarkdown = (props, cmp, customColumns = []) => {
7815
+ const content = [];
7816
+ if (props.length === 0) return content;
7817
+ content.push(`## Properties`);
7818
+ content.push(``);
7819
+ const table = new MarkdownTable();
7820
+ table.addHeader([
7821
+ "Property",
7822
+ "Attribute",
7823
+ "Description",
7824
+ "Type",
7825
+ "Default",
7826
+ ...customColumns.map((c) => c.header)
7827
+ ]);
7828
+ props.forEach((prop) => {
7829
+ table.addRow([
7830
+ getPropertyField(prop),
7831
+ getAttributeField(prop),
7832
+ getDocsField(prop),
7833
+ getTypeField(prop),
7834
+ getDefaultValueField(prop),
7835
+ ...customColumns.map((c) => c.content(prop, cmp))
7836
+ ]);
7837
+ });
7838
+ content.push(...table.toMarkdown());
7839
+ content.push(``);
7840
+ content.push(``);
7841
+ return content;
7842
+ };
7843
+ const getPropertyField = (prop) => {
7844
+ return `\`${prop.name}\`${prop.required ? " _(required)_" : ""}`;
7845
+ };
7846
+ const getAttributeField = (prop) => {
7847
+ return prop.attr ? `\`${prop.attr}\`` : "--";
7848
+ };
7849
+ const getDocsField = (prop) => {
7850
+ return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
7851
+ };
7852
+ const getTypeField = (prop) => {
7853
+ return prop.type.includes("`") ? `\`\` ${prop.type} \`\`` : `\`${prop.type}\``;
7854
+ };
7855
+ const getDefaultValueField = (prop) => {
7856
+ return prop.default?.includes("`") ? `\`\` ${prop.default} \`\`` : `\`${prop.default}\``;
7857
+ };
7858
+ //#endregion
7859
+ //#region src/compiler/docs/readme/markdown-slots.ts
7860
+ /**
7861
+ * Converts a list of Slots metadata to a table written in Markdown
7862
+ * @param slots the Slots metadata to convert
7863
+ * @returns a list of strings that make up the Markdown table
7864
+ */
7865
+ const slotsToMarkdown = (slots) => {
7866
+ const content = [];
7867
+ if (slots.length === 0) return content;
7868
+ content.push(`## Slots`);
7869
+ content.push(``);
7870
+ const table = new MarkdownTable();
7871
+ table.addHeader(["Slot", "Description"]);
7872
+ slots.forEach((style) => {
7873
+ table.addRow([style.name === "" ? "" : `\`"${style.name}"\``, style.docs]);
7874
+ });
7875
+ content.push(...table.toMarkdown());
7876
+ content.push(``);
7877
+ content.push(``);
7878
+ return content;
7879
+ };
7880
+ //#endregion
7881
+ //#region src/compiler/docs/agent-skill/markdown-component.ts
7882
+ /**
7883
+ * Generate a single component's skill reference file (`components/<tag>.md`),
7884
+ * reusing the same pure markdown-formatting functions the `docs-readme`
7885
+ * output target uses.
7886
+ * @param cmp the component's docs metadata
7887
+ * @returns the component's markdown content
7888
+ */
7889
+ const generateComponentSkillMarkdown = (cmp) => {
7890
+ return [
7891
+ `# ${cmp.tag}`,
7892
+ "",
7893
+ ...overviewToMarkdown(cmp.overview),
7894
+ ...propsToMarkdown(cmp.props),
7895
+ ...eventsToMarkdown(cmp.events),
7896
+ ...methodsToMarkdown(cmp.methods),
7897
+ ...slotsToMarkdown(cmp.slots),
7898
+ ...stylesToMarkdown(cmp.styles),
7899
+ ...partsToMarkdown(cmp.parts),
7900
+ ...usageToMarkdown(cmp.usage)
7901
+ ].join("\n");
7902
+ };
7903
+ //#endregion
7904
+ //#region src/compiler/docs/agent-skill/index.ts
7905
+ /**
7906
+ * Generate an Agent Skill (`SKILL.md` + `components/*.md`) describing the project's
7907
+ * component library.
7908
+ * @param compilerCtx the current compiler context
7909
+ * @param docsData the generated docs data
7910
+ * @param outputTargets the output targets configured for the build
7911
+ */
7912
+ const generateAgentSkillDocs = async (compilerCtx, docsData, outputTargets) => {
7913
+ const skillOutputs = outputTargets.filter(isOutputTargetDocsAgentSkill);
7914
+ if (skillOutputs.length === 0) return;
7915
+ await Promise.all(skillOutputs.map(async (outputTarget) => {
7916
+ const dir = outputTarget.dir;
7917
+ const skillMd = generateSkillMarkdown(docsData, outputTarget);
7918
+ await Promise.all([compilerCtx.fs.writeFile(join$2(dir, "SKILL.md"), skillMd), ...docsData.components.map((cmp) => compilerCtx.fs.writeFile(join$2(dir, "components", `${cmp.tag}.md`), generateComponentSkillMarkdown(cmp)))]);
7919
+ }));
7920
+ };
7921
+ //#endregion
7922
+ //#region src/compiler/docs/cem/index.ts
7923
+ /**
7924
+ * Generate Custom Elements Manifest (custom-elements.json) output
7925
+ * conforming to the Custom Elements Manifest specification.
7926
+ * @see https://github.com/webcomponents/custom-elements-manifest
7927
+ *
7928
+ * @param compilerCtx the current compiler context
7929
+ * @param docsData the generated docs data from Stencil components
7930
+ * @param outputTargets the output targets configured for the build
7931
+ */
7932
+ const generateCustomElementsManifestDocs = async (compilerCtx, docsData, outputTargets) => {
7933
+ const cemOutputTargets = outputTargets.filter(isOutputTargetDocsCustomElementsManifest);
7934
+ if (cemOutputTargets.length === 0) return;
7935
+ const manifest = generateManifest(docsData);
7936
+ const jsonContent = JSON.stringify(manifest, null, 2);
7937
+ await Promise.all(cemOutputTargets.map((outputTarget) => compilerCtx.fs.writeFile(outputTarget.file, jsonContent)));
7938
+ };
7939
+ /**
7940
+ * Generate the Custom Elements Manifest from Stencil docs data
7941
+ * @param docsData the generated docs data
7942
+ * @returns the Custom Elements Manifest object
7943
+ */
7944
+ const generateManifest = (docsData) => {
7945
+ const componentsByFile = /* @__PURE__ */ new Map();
7946
+ for (const component of docsData.components) {
7947
+ const filePath = component.filePath;
7948
+ if (!componentsByFile.has(filePath)) componentsByFile.set(filePath, []);
7949
+ componentsByFile.get(filePath).push(component);
7950
+ }
7951
+ const modules = [];
7952
+ for (const [filePath, components] of componentsByFile) {
7953
+ const declarations = components.map((component) => componentToDeclaration(component));
7954
+ const exports = components.flatMap((component) => {
7955
+ const className = dashToPascalCase(component.tag);
7956
+ return [{
7957
+ kind: "js",
7958
+ name: className,
7959
+ declaration: { name: className }
7960
+ }, {
7961
+ kind: "custom-element-definition",
7962
+ name: component.tag,
7963
+ declaration: { name: className }
7964
+ }];
7965
+ });
7966
+ modules.push({
7967
+ kind: "javascript-module",
7968
+ path: filePath,
7969
+ declarations,
7970
+ exports
7971
+ });
7972
+ }
7973
+ return {
7974
+ schemaVersion: "2.1.0",
7975
+ modules
7976
+ };
7977
+ };
7978
+ /**
7979
+ * Convert Stencil's ComponentCompilerTypeReferences to CEM TypeReference array
7396
7980
  * @param references Stencil's type references map
7397
7981
  * @returns CEM TypeReference array
7398
7982
  */
@@ -7568,145 +8152,17 @@ export default _default;
7568
8152
  states: cmp.customStates,
7569
8153
  dependents: cmp.dependents,
7570
8154
  dependencies: cmp.dependencies,
7571
- dependencyGraph: cmp.dependencyGraph,
7572
- deprecation: cmp.deprecation
7573
- }))
7574
- };
7575
- const jsonContent = JSON.stringify(json, null, 2);
7576
- await Promise.all(jsonOutputTargets.map((jsonOutput) => {
7577
- return writeDocsOutput(compilerCtx, jsonOutput, jsonContent, typesContent);
7578
- }));
7579
- };
7580
- const writeDocsOutput = async (compilerCtx, jsonOutput, jsonContent, typesContent) => {
7581
- return Promise.all([compilerCtx.fs.writeFile(jsonOutput.file, jsonContent), jsonOutput.typesFile ? compilerCtx.fs.writeFile(jsonOutput.typesFile, typesContent) : Promise.resolve()]);
7582
- };
7583
- //#endregion
7584
- //#region src/compiler/docs/readme/docs-util.ts
7585
- var MarkdownTable = class {
7586
- rows = [];
7587
- addHeader(data) {
7588
- this.addRow(data, true);
7589
- }
7590
- addRow(data, isHeader = false) {
7591
- const colData = [];
7592
- data.forEach((text) => {
7593
- const col = {
7594
- text: escapeMarkdownTableColumn(text),
7595
- width: text.length
7596
- };
7597
- colData.push(col);
7598
- });
7599
- this.rows.push({
7600
- columns: colData,
7601
- isHeader
7602
- });
7603
- }
7604
- toMarkdown() {
7605
- return createTable(this.rows);
7606
- }
7607
- };
7608
- const escapeMarkdownTableColumn = (text) => {
7609
- text = text.replace(/\r?\n/g, " ");
7610
- text = text.replace(/\|/g, "\\|");
7611
- return text;
7612
- };
7613
- const createTable = (rows) => {
7614
- const content = [];
7615
- if (rows.length === 0) return content;
7616
- normalizeColumCount(rows);
7617
- normalizeColumnWidth(rows);
7618
- const th = rows.find((r) => r.isHeader);
7619
- if (th) {
7620
- const headerRow = createRow(th);
7621
- content.push(headerRow);
7622
- content.push(createBorder(th));
7623
- }
7624
- rows.filter((r) => !r.isHeader).forEach((td) => {
7625
- content.push(createRow(td));
7626
- });
7627
- return content;
7628
- };
7629
- const createBorder = (th) => {
7630
- const border = {
7631
- columns: [],
7632
- isHeader: false
7633
- };
7634
- th.columns.forEach((c) => {
7635
- const borderCol = {
7636
- text: "",
7637
- width: c.width
7638
- };
7639
- while (borderCol.text.length < borderCol.width) borderCol.text += "-";
7640
- border.columns.push(borderCol);
7641
- });
7642
- return createRow(border);
7643
- };
7644
- const createRow = (row) => {
7645
- const content = ["| "];
7646
- row.columns.forEach((c) => {
7647
- content.push(c.text);
7648
- content.push(" | ");
7649
- });
7650
- return content.join("").trim();
7651
- };
7652
- const normalizeColumCount = (rows) => {
7653
- let columnCount = 0;
7654
- rows.forEach((r) => {
7655
- if (r.columns.length > columnCount) columnCount = r.columns.length;
7656
- });
7657
- rows.forEach((r) => {
7658
- while (r.columns.length < columnCount) r.columns.push({
7659
- text: ``,
7660
- width: 0
7661
- });
7662
- });
7663
- };
7664
- const normalizeColumnWidth = (rows) => {
7665
- const columnCount = rows[0].columns.length;
7666
- for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) {
7667
- let longestText = 0;
7668
- rows.forEach((r) => {
7669
- const col = r.columns[columnIndex];
7670
- if (col.text.length > longestText) longestText = col.text.length;
7671
- });
7672
- rows.forEach((r) => {
7673
- const col = r.columns[columnIndex];
7674
- col.width = longestText;
7675
- while (col.text.length < longestText) col.text += " ";
7676
- });
7677
- }
7678
- };
7679
- /**
7680
- * Checks if a given string is a valid hexadecimal color representation.
7681
- *
7682
- * @param str - The string to be checked.
7683
- * @returns `true` if the string is a valid hex color (e.g., '#FF00AA', '#f0f'), `false` otherwise.
7684
- *
7685
- * @example
7686
- * isHexColor('#FF00AA'); // true
7687
- * isHexColor('#f0f'); // true
7688
- * isHexColor('#abcde'); // false (too many characters)
7689
- * isHexColor('FF00AA'); // false (missing #)
7690
- */
7691
- const isHexColor = (str) => {
7692
- return /^#([0-9A-Fa-f]{3}){1,2}$/.test(str);
8155
+ dependencyGraph: cmp.dependencyGraph,
8156
+ deprecation: cmp.deprecation
8157
+ }))
8158
+ };
8159
+ const jsonContent = JSON.stringify(json, null, 2);
8160
+ await Promise.all(jsonOutputTargets.map((jsonOutput) => {
8161
+ return writeDocsOutput(compilerCtx, jsonOutput, jsonContent, typesContent);
8162
+ }));
7693
8163
  };
7694
- //#endregion
7695
- //#region src/compiler/docs/readme/markdown-css-props.ts
7696
- const stylesToMarkdown = (styles) => {
7697
- const content = [];
7698
- if (styles.length === 0) return content;
7699
- content.push(`## CSS Custom Properties`);
7700
- content.push(``);
7701
- const table = new MarkdownTable();
7702
- table.addHeader(["Name", "Description"]);
7703
- styles.forEach((style) => {
7704
- table.addRow([`\`${style.name}\``, style.docs]);
7705
- });
7706
- content.push(...table.toMarkdown());
7707
- content.push(``);
7708
- content.push(``);
7709
- return content;
8164
+ const writeDocsOutput = async (compilerCtx, jsonOutput, jsonContent, typesContent) => {
8165
+ return Promise.all([compilerCtx.fs.writeFile(jsonOutput.file, jsonContent), jsonOutput.typesFile ? compilerCtx.fs.writeFile(jsonOutput.typesFile, typesContent) : Promise.resolve()]);
7710
8166
  };
7711
8167
  //#endregion
7712
8168
  //#region src/compiler/docs/readme/markdown-custom-states.ts
@@ -7780,220 +8236,6 @@ const getCmpLink = (from, to, cmps) => {
7780
8236
  return to;
7781
8237
  };
7782
8238
  //#endregion
7783
- //#region src/compiler/docs/readme/markdown-events.ts
7784
- const eventsToMarkdown = (events) => {
7785
- const content = [];
7786
- if (events.length === 0) return content;
7787
- content.push(`## Events`);
7788
- content.push(``);
7789
- const table = new MarkdownTable();
7790
- table.addHeader([
7791
- "Event",
7792
- "Description",
7793
- "Type"
7794
- ]);
7795
- events.forEach((ev) => {
7796
- table.addRow([
7797
- `\`${ev.event}\``,
7798
- getDocsField$2(ev),
7799
- `\`CustomEvent<${ev.detail}>\``
7800
- ]);
7801
- });
7802
- content.push(...table.toMarkdown());
7803
- content.push(``);
7804
- content.push(``);
7805
- return content;
7806
- };
7807
- const getDocsField$2 = (prop) => {
7808
- return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
7809
- };
7810
- //#endregion
7811
- //#region src/compiler/docs/readme/markdown-methods.ts
7812
- const methodsToMarkdown = (methods) => {
7813
- const content = [];
7814
- if (methods.length === 0) return content;
7815
- content.push(`## Methods`);
7816
- content.push(``);
7817
- methods.forEach((method) => {
7818
- content.push(`### \`${method.signature}\``);
7819
- content.push(``);
7820
- content.push(getDocsField$1(method));
7821
- content.push(``);
7822
- if (method.parameters.length > 0) {
7823
- const parmsTable = new MarkdownTable();
7824
- parmsTable.addHeader([
7825
- "Name",
7826
- "Type",
7827
- "Description"
7828
- ]);
7829
- method.parameters.forEach(({ name, type, docs }) => {
7830
- parmsTable.addRow([
7831
- "`" + name + "`",
7832
- "`" + type + "`",
7833
- docs
7834
- ]);
7835
- });
7836
- content.push(`#### Parameters`);
7837
- content.push(``);
7838
- content.push(...parmsTable.toMarkdown());
7839
- content.push(``);
7840
- }
7841
- if (method.returns) {
7842
- content.push(`#### Returns`);
7843
- content.push(``);
7844
- content.push(`Type: \`${method.returns.type}\``);
7845
- content.push(``);
7846
- content.push(method.returns.docs);
7847
- content.push(``);
7848
- }
7849
- });
7850
- content.push(``);
7851
- return content;
7852
- };
7853
- const getDocsField$1 = (prop) => {
7854
- return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
7855
- };
7856
- //#endregion
7857
- //#region src/compiler/docs/readme/markdown-overview.ts
7858
- /**
7859
- * Generate an 'Overview' section for a markdown file
7860
- * @param overview a component-level comment string to place in a markdown file
7861
- * @returns The generated Overview section. If the provided overview is empty, return an empty list
7862
- */
7863
- const overviewToMarkdown = (overview) => {
7864
- if (!overview) return [];
7865
- const content = [];
7866
- content.push(`## Overview`);
7867
- content.push("");
7868
- content.push(`${overview.trim()}`);
7869
- content.push("");
7870
- return content;
7871
- };
7872
- //#endregion
7873
- //#region src/compiler/docs/readme/markdown-parts.ts
7874
- /**
7875
- * Converts a list of Shadow Parts metadata to a table written in Markdown
7876
- * @param parts the Shadow parts metadata to convert
7877
- * @returns a list of strings that make up the Markdown table
7878
- */
7879
- const partsToMarkdown = (parts) => {
7880
- const content = [];
7881
- if (parts.length === 0) return content;
7882
- content.push(`## Shadow Parts`);
7883
- content.push(``);
7884
- const table = new MarkdownTable();
7885
- table.addHeader(["Part", "Description"]);
7886
- parts.forEach((style) => {
7887
- table.addRow([style.name === "" ? "" : `\`"${style.name}"\``, style.docs]);
7888
- });
7889
- content.push(...table.toMarkdown());
7890
- content.push(``);
7891
- content.push(``);
7892
- return content;
7893
- };
7894
- //#endregion
7895
- //#region src/compiler/docs/readme/markdown-props.ts
7896
- const propsToMarkdown = (props) => {
7897
- const content = [];
7898
- if (props.length === 0) return content;
7899
- content.push(`## Properties`);
7900
- content.push(``);
7901
- const table = new MarkdownTable();
7902
- table.addHeader([
7903
- "Property",
7904
- "Attribute",
7905
- "Description",
7906
- "Type",
7907
- "Default"
7908
- ]);
7909
- props.forEach((prop) => {
7910
- table.addRow([
7911
- getPropertyField(prop),
7912
- getAttributeField(prop),
7913
- getDocsField(prop),
7914
- getTypeField(prop),
7915
- getDefaultValueField(prop)
7916
- ]);
7917
- });
7918
- content.push(...table.toMarkdown());
7919
- content.push(``);
7920
- content.push(``);
7921
- return content;
7922
- };
7923
- const getPropertyField = (prop) => {
7924
- return `\`${prop.name}\`${prop.required ? " _(required)_" : ""}`;
7925
- };
7926
- const getAttributeField = (prop) => {
7927
- return prop.attr ? `\`${prop.attr}\`` : "--";
7928
- };
7929
- const getDocsField = (prop) => {
7930
- return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
7931
- };
7932
- const getTypeField = (prop) => {
7933
- return prop.type.includes("`") ? `\`\` ${prop.type} \`\`` : `\`${prop.type}\``;
7934
- };
7935
- const getDefaultValueField = (prop) => {
7936
- return prop.default?.includes("`") ? `\`\` ${prop.default} \`\`` : `\`${prop.default}\``;
7937
- };
7938
- //#endregion
7939
- //#region src/compiler/docs/readme/markdown-slots.ts
7940
- /**
7941
- * Converts a list of Slots metadata to a table written in Markdown
7942
- * @param slots the Slots metadata to convert
7943
- * @returns a list of strings that make up the Markdown table
7944
- */
7945
- const slotsToMarkdown = (slots) => {
7946
- const content = [];
7947
- if (slots.length === 0) return content;
7948
- content.push(`## Slots`);
7949
- content.push(``);
7950
- const table = new MarkdownTable();
7951
- table.addHeader(["Slot", "Description"]);
7952
- slots.forEach((style) => {
7953
- table.addRow([style.name === "" ? "" : `\`"${style.name}"\``, style.docs]);
7954
- });
7955
- content.push(...table.toMarkdown());
7956
- content.push(``);
7957
- content.push(``);
7958
- return content;
7959
- };
7960
- //#endregion
7961
- //#region src/compiler/docs/readme/markdown-usage.ts
7962
- const usageToMarkdown = (usages) => {
7963
- const content = [];
7964
- const merged = mergeUsages(usages);
7965
- if (merged.length === 0) return content;
7966
- content.push(`## Usage`);
7967
- merged.forEach(({ name, text }) => {
7968
- content.push("");
7969
- content.push(`### ${toTitleCase(name)}`);
7970
- content.push("");
7971
- content.push(text);
7972
- content.push("");
7973
- });
7974
- content.push("");
7975
- content.push("");
7976
- return content;
7977
- };
7978
- const mergeUsages = (usages) => {
7979
- const keys = Object.keys(usages);
7980
- const map = /* @__PURE__ */ new Map();
7981
- keys.forEach((key) => {
7982
- const usage = usages[key].trim();
7983
- const array = map.get(usage) || [];
7984
- array.push(key);
7985
- map.set(usage, array);
7986
- });
7987
- const merged = [];
7988
- map.forEach((value, key) => {
7989
- merged.push({
7990
- name: value.join(" / "),
7991
- text: key
7992
- });
7993
- });
7994
- return merged;
7995
- };
7996
- //#endregion
7997
8239
  //#region src/compiler/docs/readme/output-docs.ts
7998
8240
  /**
7999
8241
  * Generate a README for a given component and write it to disk.
@@ -8019,7 +8261,8 @@ const generateReadme = async (config, compilerCtx, readmeOutputs, docsData, cmps
8019
8261
  if (readmeOutput.dir) {
8020
8262
  const relativeReadmePath = relative$1(config.srcDir, docsData.readmePath);
8021
8263
  const readmeOutputPath = join$2(readmeOutput.dir, relativeReadmePath);
8022
- const readmeContent = generateMarkdown(await resolveUserContent(compilerCtx, readmeOutput, readmeOutputPath, config, userContent), docsData, cmps, readmeOutput, config);
8264
+ const currentReadmeContent = await resolveUserContent(compilerCtx, readmeOutput, readmeOutputPath, config, userContent);
8265
+ const readmeContent = generateMarkdown(currentReadmeContent, docsData, cmps, readmeOutput, config);
8023
8266
  if ((await compilerCtx.fs.readFile(readmeOutputPath))?.replace(/\r/g, "") === readmeContent.replace(/\r/g, "")) return;
8024
8267
  await compilerCtx.fs.writeFile(readmeOutputPath, readmeContent);
8025
8268
  if (isUpdate) config.logger.info(`updated readme docs: ${docsData.tag}`);
@@ -8048,7 +8291,8 @@ const generateMergedReadme = async (config, compilerCtx, readmeOutputs, cmps, al
8048
8291
  if (readmeOutput.dir) {
8049
8292
  const relativeReadmePath = relative$1(config.srcDir, primaryCmp.readmePath);
8050
8293
  const readmeOutputPath = join$2(readmeOutput.dir, relativeReadmePath);
8051
- const readmeContent = generateMergedMarkdown(await resolveUserContent(compilerCtx, readmeOutput, readmeOutputPath, config, userContent), cmps, allCmps, readmeOutput, config);
8294
+ const currentReadmeContent = await resolveUserContent(compilerCtx, readmeOutput, readmeOutputPath, config, userContent);
8295
+ const readmeContent = generateMergedMarkdown(currentReadmeContent, cmps, allCmps, readmeOutput, config);
8052
8296
  if ((await compilerCtx.fs.readFile(readmeOutputPath))?.replace(/\r/g, "") === readmeContent.replace(/\r/g, "")) return;
8053
8297
  await compilerCtx.fs.writeFile(readmeOutputPath, readmeContent);
8054
8298
  const tags = cmps.map((c) => c.tag).join(", ");
@@ -8104,8 +8348,8 @@ const generateComponentBody = (cmp, cmps, readmeOutput, config) => {
8104
8348
  ...getDocsDeprecation(cmp),
8105
8349
  ...overviewToMarkdown(cmp.overview),
8106
8350
  ...usageToMarkdown(cmp.usage),
8107
- ...propsToMarkdown(cmp.props),
8108
- ...eventsToMarkdown(cmp.events),
8351
+ ...propsToMarkdown(cmp.props, cmp, readmeOutput.customColumns?.props),
8352
+ ...eventsToMarkdown(cmp.events, cmp, readmeOutput.customColumns?.events),
8109
8353
  ...methodsToMarkdown(cmp.methods),
8110
8354
  ...slotsToMarkdown(cmp.slots),
8111
8355
  ...partsToMarkdown(cmp.parts),
@@ -8305,14 +8549,15 @@ const serializeAttribute = (prop) => {
8305
8549
  * @param buildCtx the build context for the current Stencil task run
8306
8550
  */
8307
8551
  const outputDocs = async (config, compilerCtx, buildCtx) => {
8308
- const docsOutputTargets = filterActiveTargets(config.outputTargets.filter((o) => isOutputTargetDocsReadme(o) || isOutputTargetDocsJson(o) || isOutputTargetDocsCustom(o) || isOutputTargetDocsVscode(o) || isOutputTargetDocsCustomElementsManifest(o)), config.devMode);
8552
+ const docsOutputTargets = filterActiveTargets(config.outputTargets.filter((o) => isOutputTargetDocsReadme(o) || isOutputTargetDocsJson(o) || isOutputTargetDocsCustom(o) || isOutputTargetDocsVscode(o) || isOutputTargetDocsCustomElementsManifest(o) || isOutputTargetDocsAgentSkill(o)), config.devMode);
8309
8553
  if (docsOutputTargets.length === 0) return;
8310
8554
  await buildCtx.stylesPromise;
8311
8555
  const docsData = await generateDocData(config, compilerCtx, buildCtx);
8312
- if (config.outputTargets.every((target) => target.type === "docs-readme" || target.type === "docs-json" || target.type === "docs-custom" || target.type === "docs-vscode" || target.type === "docs-custom-elements-manifest")) await Promise.all(docsData.components.map(async (component) => {
8556
+ if (config.outputTargets.every((target) => target.type === "docs-readme" || target.type === "docs-json" || target.type === "docs-custom" || target.type === "docs-vscode" || target.type === "docs-custom-elements-manifest" || target.type === "docs-agent-skill")) await Promise.all(docsData.components.map(async (component) => {
8313
8557
  if (component.styles.length === 0) {
8314
8558
  const readmeDir = docsOutputTargets.find(isOutputTargetDocsReadme)?.dir || config.srcDir;
8315
- const existingCssProps = await extractExistingCssProps(compilerCtx, normalizePath(readmeDir) === normalizePath(config.srcDir) ? component.readmePath : join$2(readmeDir, component.readmePath.replace(config.srcDir, "")));
8559
+ const readmePath = normalizePath(readmeDir) === normalizePath(config.srcDir) ? component.readmePath : join$2(readmeDir, component.readmePath.replace(config.srcDir, ""));
8560
+ const existingCssProps = await extractExistingCssProps(compilerCtx, readmePath);
8316
8561
  if (existingCssProps) component.styles = existingCssProps;
8317
8562
  }
8318
8563
  }));
@@ -8321,7 +8566,8 @@ const outputDocs = async (config, compilerCtx, buildCtx) => {
8321
8566
  generateJsonDocs(config, compilerCtx, docsData, docsOutputTargets),
8322
8567
  generateVscodeDocs(compilerCtx, docsData, docsOutputTargets),
8323
8568
  generateCustomDocs(config, docsData, docsOutputTargets),
8324
- generateCustomElementsManifestDocs(compilerCtx, docsData, docsOutputTargets)
8569
+ generateCustomElementsManifestDocs(compilerCtx, docsData, docsOutputTargets),
8570
+ generateAgentSkillDocs(compilerCtx, docsData, docsOutputTargets)
8325
8571
  ]);
8326
8572
  };
8327
8573
  //#endregion
@@ -8355,7 +8601,8 @@ const outputGlobalStyle = async (config, compilerCtx, buildCtx) => {
8355
8601
  const primaryPath = join$2(outputTarget.dir, outputTarget.fileName);
8356
8602
  writePromises.push(compilerCtx.fs.writeFile(primaryPath, css, { outputTargetType: outputTarget.type }));
8357
8603
  if (outputTarget.copyToLoaderBrowser && loaderBundleTargets.length > 0) for (const loaderTarget of loaderBundleTargets) {
8358
- const compatPath = join$2(join$2(loaderTarget.buildDir, namespace), outputTarget.fileName);
8604
+ const browserDir = join$2(loaderTarget.buildDir, namespace);
8605
+ const compatPath = join$2(browserDir, outputTarget.fileName);
8359
8606
  writePromises.push(compilerCtx.fs.writeFile(compatPath, css));
8360
8607
  }
8361
8608
  for (const wwwTarget of wwwTargets) {
@@ -8405,7 +8652,8 @@ const generateStandaloneTypesOutput = async (config, compilerCtx, buildCtx, type
8405
8652
  ...components.map((component) => {
8406
8653
  const exportName = dashToPascalCase(component.tagName);
8407
8654
  const importName = component.componentClassName;
8408
- const componentDTSPath = join$2(componentsTypeDirectoryRelPath, relative$1(config.srcDir, component.sourceFilePath).replace(/\.tsx$/, ""));
8655
+ const componentSourceRelPath = relative$1(config.srcDir, component.sourceFilePath).replace(/\.tsx$/, "");
8656
+ const componentDTSPath = join$2(componentsTypeDirectoryRelPath, componentSourceRelPath);
8409
8657
  const defineFunctionExportName = `defineCustomElement${exportName}`;
8410
8658
  const localComponentTypeDefFilePath = `./${component.tagName}`;
8411
8659
  return [`export { ${importName} as ${exportName} } from '${componentDTSPath.startsWith(".") ? componentDTSPath : "./" + componentDTSPath}';`, `export { defineCustomElement as ${defineFunctionExportName} } from '${localComponentTypeDefFilePath}';`].join("\n");
@@ -8476,8 +8724,9 @@ const generateCustomElementType = (componentsDtsRelPath, cmp) => {
8476
8724
  const tagNameAsPascal = dashToPascalCase(cmp.tagName);
8477
8725
  return [
8478
8726
  `import type { Components, JSX } from "${componentsDtsRelPath}";`,
8727
+ `import type { HTMLStencilElement } from "@stencil/core/runtime";`,
8479
8728
  ``,
8480
- `interface ${tagNameAsPascal} extends Components.${tagNameAsPascal}, HTMLElement {}`,
8729
+ `interface ${tagNameAsPascal} extends Components.${tagNameAsPascal}, HTMLStencilElement {}`,
8481
8730
  `export const ${tagNameAsPascal}: {`,
8482
8731
  ` prototype: ${tagNameAsPascal};`,
8483
8732
  ` new (): ${tagNameAsPascal};`,
@@ -8502,7 +8751,7 @@ const relDts = (fromPath, dtsPath) => {
8502
8751
  };
8503
8752
  //#endregion
8504
8753
  //#region src/compiler/types/constants.ts
8505
- const HTML_ELEMENT_METHODS = new Set([
8754
+ const HTML_ELEMENT_METHODS = /* @__PURE__ */ new Set([
8506
8755
  "attachInternals",
8507
8756
  "blur",
8508
8757
  "click",
@@ -8595,7 +8844,9 @@ const HTML_ELEMENT_METHODS = new Set([
8595
8844
  * @returns the updated type declaration file contents
8596
8845
  */
8597
8846
  const updateStencilTypesImports = (typesDir, dtsFilePath, dtsContent) => {
8598
- let coreDtsPath = join$2(relative$1(dirname$1(dtsFilePath), typesDir), CORE_FILENAME);
8847
+ const dir = dirname$1(dtsFilePath);
8848
+ const relPath = relative$1(dir, typesDir);
8849
+ let coreDtsPath = join$2(relPath, CORE_FILENAME);
8599
8850
  if (!coreDtsPath.startsWith(".")) coreDtsPath = `./${coreDtsPath}`;
8600
8851
  coreDtsPath = normalizePath(coreDtsPath);
8601
8852
  if (dtsContent.includes("@stencil/core")) {
@@ -8733,7 +8984,8 @@ const CORE_DTS = `${CORE_FILENAME}.d.ts`;
8733
8984
  * @returns additional types information to add event listener method overloads for component's html element type
8734
8985
  */
8735
8986
  const generateEventListenerTypes = (cmp, typeImportData) => {
8736
- const tagNameAsPascal = dashToPascalCase(cmp.tagName.toLowerCase());
8987
+ const tagName = cmp.tagName.toLowerCase();
8988
+ const tagNameAsPascal = dashToPascalCase(tagName);
8737
8989
  const htmlElementName = `HTML${tagNameAsPascal}Element`;
8738
8990
  const cmpEventInterface = `${tagNameAsPascal}CustomEvent`;
8739
8991
  const htmlElementEventMapName = `${htmlElementName}EventMap`;
@@ -8799,9 +9051,11 @@ const getEventGenericType = (cmpEvent, typeImportData, componentSourcePath) => {
8799
9051
  */
8800
9052
  const generateEventTypes = (cmpMeta, typeImportData, cmpClassName) => {
8801
9053
  return cmpMeta.events.map((cmpEvent) => {
9054
+ const name = `on${toTitleCase(cmpEvent.name)}`;
9055
+ const cmpEventDetailInterface = `${cmpClassName}CustomEvent`;
8802
9056
  return {
8803
- name: `on${toTitleCase(cmpEvent.name)}`,
8804
- type: getEventType$1(cmpEvent, `${cmpClassName}CustomEvent`, typeImportData, cmpMeta.sourceFilePath),
9057
+ name,
9058
+ type: getEventType$1(cmpEvent, cmpEventDetailInterface, typeImportData, cmpMeta.sourceFilePath),
8805
9059
  optional: false,
8806
9060
  required: false,
8807
9061
  internal: cmpEvent.internal,
@@ -9212,6 +9466,12 @@ const updateImportReferenceFactory = (typeCounts, filePath, config) => {
9212
9466
  //#endregion
9213
9467
  //#region src/compiler/types/generate-app-types.ts
9214
9468
  /**
9469
+ * Above this many required props on a single component, the generated `OneOf<>` required-prop
9470
+ * check is skipped entirely (falling back to unchecked optional `attr:`/`prop:` variants) rather
9471
+ * than risking exponential failure in the TS checker - see the comment at its usage site.
9472
+ */
9473
+ const MAX_ONE_OF_REQUIRED_PROPS = 8;
9474
+ /**
9215
9475
  * Generates and writes a `components.d.ts` file to disk. This file may be written to the `src` directory of a project,
9216
9476
  * or be written to a directory that is meant to be distributed.
9217
9477
  * @param config the Stencil configuration associated with the project being compiled
@@ -9275,20 +9535,26 @@ const generateComponentTypesFile = (config, buildCtx, areTypesInternal) => {
9275
9535
  const typeData = typeImportData[filePath];
9276
9536
  let importFilePath = filePath;
9277
9537
  if (isAbsolute$1(filePath)) importFilePath = normalizePath("./" + relative$1(config.srcDir, filePath)).replace(/\.(tsx|ts)$/, "");
9278
- const hasDefaultImport = typeData.some((td) => td.isDefault);
9279
- if (hasDefaultImport && typeData.length === 1) {
9280
- const td = typeData[0];
9281
- imports.push(`import ${td.importName} from "${importFilePath}";`);
9282
- exports.push(`export { default as ${td.importName} } from "${importFilePath}";`);
9283
- } else if (hasDefaultImport) {
9284
- const defaultImport = typeData.find((td) => td.isDefault);
9285
- const namedPart = typeData.filter((td) => !td.isDefault).sort(sortImportNames).map((td) => {
9538
+ const defaultImports = typeData.filter((td) => td.isDefault);
9539
+ if (defaultImports.length > 0) {
9540
+ const [defaultImport, ...additionalDefaultImports] = defaultImports;
9541
+ const namedImports = typeData.filter((td) => !td.isDefault);
9542
+ const namedPart = namedImports.sort(sortImportNames).map((td) => {
9286
9543
  if (td.originalName === "") return `${td.localName}`;
9287
9544
  else if (td.originalName === td.importName) return `${td.originalName}`;
9288
9545
  else return `${td.originalName} as ${td.importName}`;
9289
9546
  }).join(`, `);
9290
- imports.push(`import ${defaultImport.importName}, { ${namedPart} } from "${importFilePath}";`);
9291
- exports.push(`export { default as ${defaultImport.importName}, ${namedPart} } from "${importFilePath}";`);
9547
+ if (namedImports.length > 0) {
9548
+ imports.push(`import ${defaultImport.importName}, { ${namedPart} } from "${importFilePath}";`);
9549
+ exports.push(`export { default as ${defaultImport.importName}, ${namedPart} } from "${importFilePath}";`);
9550
+ } else {
9551
+ imports.push(`import ${defaultImport.importName} from "${importFilePath}";`);
9552
+ exports.push(`export { default as ${defaultImport.importName} } from "${importFilePath}";`);
9553
+ }
9554
+ additionalDefaultImports.forEach((td) => {
9555
+ imports.push(`import ${td.importName} from "${importFilePath}";`);
9556
+ exports.push(`export { default as ${td.importName} } from "${importFilePath}";`);
9557
+ });
9292
9558
  } else {
9293
9559
  const namedPart = typeData.sort(sortImportNames).map((td) => {
9294
9560
  if (td.originalName === "") return `${td.localName}`;
@@ -9311,8 +9577,8 @@ const generateComponentTypesFile = (config, buildCtx, areTypesInternal) => {
9311
9577
  c.push(` }`);
9312
9578
  c.push(`}`);
9313
9579
  c.push(`declare namespace LocalJSX {`);
9314
- if (modules.some((m) => m.requiredProps)) {
9315
- c.push(` type OneOf<K extends string, PropT, AttrT = PropT> = { [P in K]: PropT } & { [P in \`attr:\${K}\` | \`prop:\${K}\`]?: never } | { [P in \`attr:\${K}\`]: AttrT } & { [P in K | \`prop:\${K}\`]?: never } | { [P in \`prop:\${K}\`]: PropT } & { [P in K | \`attr:\${K}\`]?: never };`);
9580
+ if (modules.some((m) => m.requiredProps && m.requiredProps.length > 0 && m.requiredProps.length <= MAX_ONE_OF_REQUIRED_PROPS)) {
9581
+ c.push(` type OneOf<K extends string, PropT, AttrT = PropT> = { [P in K]: PropT } & { [P in \`attr:\${K}\`]?: never } | { [P in \`attr:\${K}\`]: AttrT } & { [P in K]?: never };`);
9316
9582
  c.push(``);
9317
9583
  }
9318
9584
  c.push(...modules.map((m) => {
@@ -9329,7 +9595,7 @@ const generateComponentTypesFile = (config, buildCtx, areTypesInternal) => {
9329
9595
  c.push(...modules.map((m) => {
9330
9596
  if (m.explicitAttributes) {
9331
9597
  const baseOptional = `Omit<${m.tagNameAsPascal}, keyof ${m.tagNameAsPascal}Attributes> & { [K in keyof ${m.tagNameAsPascal} & keyof ${m.tagNameAsPascal}Attributes]?: ${m.tagNameAsPascal}[K] } & { [K in keyof ${m.tagNameAsPascal} & keyof ${m.tagNameAsPascal}Attributes as \`attr:\${K}\`]?: ${m.tagNameAsPascal}Attributes[K] } & { [K in keyof ${m.tagNameAsPascal} & keyof ${m.tagNameAsPascal}Attributes as \`prop:\${K}\`]?: ${m.tagNameAsPascal}[K] }`;
9332
- if (m.requiredProps && m.requiredProps.length > 0) {
9598
+ if (m.requiredProps && m.requiredProps.length > 0 && m.requiredProps.length <= MAX_ONE_OF_REQUIRED_PROPS) {
9333
9599
  const requiredUnions = m.requiredProps.map((prop) => {
9334
9600
  return `OneOf<"${prop.name}", ${m.tagNameAsPascal}["${prop.name}"], ${m.tagNameAsPascal}Attributes["${prop.name}"]>`;
9335
9601
  }).join(" & ");
@@ -9508,7 +9774,8 @@ const outputTypes = async (config, compilerCtx, buildCtx) => {
9508
9774
  * @returns a path to the build directory for that output target
9509
9775
  */
9510
9776
  const getAbsoluteBuildDir = (outputTarget) => {
9511
- return join$2("/", relative$1(outputTarget.dir, outputTarget.buildDir)) + "/";
9777
+ const relativeBuildDir = relative$1(outputTarget.dir, outputTarget.buildDir);
9778
+ return join$2("/", relativeBuildDir) + "/";
9512
9779
  };
9513
9780
  //#endregion
9514
9781
  //#region src/compiler/html/add-script-attr.ts
@@ -9528,7 +9795,8 @@ const addScriptDataAttribute = (config, doc, outputTarget) => {
9528
9795
  //#region src/compiler/html/inject-module-preloads.ts
9529
9796
  const optimizeCriticalPath = (doc, criticalBundlers, outputTarget) => {
9530
9797
  const buildDir = getAbsoluteBuildDir(outputTarget);
9531
- injectModulePreloads(doc, criticalBundlers.map((path) => join$2(buildDir, path)));
9798
+ const paths = criticalBundlers.map((path) => join$2(buildDir, path));
9799
+ injectModulePreloads(doc, paths);
9532
9800
  };
9533
9801
  const injectModulePreloads = (doc, paths) => {
9534
9802
  const existingLinks = Array.from(doc.querySelectorAll("link[rel=modulepreload]")).map((link) => link.getAttribute("href"));
@@ -9658,7 +9926,8 @@ const updateIndexHtmlServiceWorker = async (config, buildCtx, doc, outputTarget)
9658
9926
  else if (serviceWorker) await injectRegisterServiceWorker(buildCtx, outputTarget, doc);
9659
9927
  };
9660
9928
  const injectRegisterServiceWorker = async (buildCtx, outputTarget, doc) => {
9661
- const serviceWorker = getRegisterSwScript(doc, buildCtx, generateServiceWorkerUrl(outputTarget, outputTarget.serviceWorker));
9929
+ const swUrl = generateServiceWorkerUrl(outputTarget, outputTarget.serviceWorker);
9930
+ const serviceWorker = getRegisterSwScript(doc, buildCtx, swUrl);
9662
9931
  doc.body.appendChild(serviceWorker);
9663
9932
  };
9664
9933
  const injectUnregisterServiceWorker = (doc) => {
@@ -9828,7 +10097,7 @@ function readModulePaths(code) {
9828
10097
  function isImportOrExportDecl(stmt) {
9829
10098
  return ts.isExportDeclaration(stmt) || ts.isImportDeclaration(stmt);
9830
10099
  }
9831
- const MAX_JS_INLINE_SIZE = 1 * 1024;
10100
+ const MAX_JS_INLINE_SIZE = 1024;
9832
10101
  //#endregion
9833
10102
  //#region src/compiler/html/inline-style-sheets.ts
9834
10103
  const inlineStyleSheets = (compilerCtx, doc, maxSize, outputTarget) => {
@@ -9930,7 +10199,10 @@ const generateWww = async (config, compilerCtx, buildCtx, criticalPath, outputTa
9930
10199
  }
9931
10200
  if (!skipHtml) {
9932
10201
  if (buildCtx.indexDoc && outputTarget.indexHtml) await generateIndexHtml(config, compilerCtx, buildCtx, criticalPath, outputTarget, globalStylesMap);
9933
- for (const [relPath, doc] of buildCtx.htmlDocs) await generateHtmlFile(config, compilerCtx, buildCtx, doc, join$2(outputTarget.appDir, relPath), outputTarget, globalStylesMap);
10202
+ for (const [relPath, doc] of buildCtx.htmlDocs) {
10203
+ const destPath = join$2(outputTarget.appDir, relPath);
10204
+ await generateHtmlFile(config, compilerCtx, buildCtx, doc, destPath, outputTarget, globalStylesMap);
10205
+ }
9934
10206
  }
9935
10207
  await generateHostConfig(compilerCtx, outputTarget);
9936
10208
  };
@@ -10015,24 +10287,26 @@ const generateIndexHtml = async (config, compilerCtx, buildCtx, criticalPath, ou
10015
10287
  */
10016
10288
  const generateHtmlFile = async (config, compilerCtx, buildCtx, doc, destPath, outputTarget, globalStylesMap) => {
10017
10289
  try {
10018
- await processHtmlDoc(config, compilerCtx, buildCtx, cloneDocument(doc), destPath, outputTarget, globalStylesMap);
10290
+ const cloned = cloneDocument(doc);
10291
+ await processHtmlDoc(config, compilerCtx, buildCtx, cloned, destPath, outputTarget, globalStylesMap);
10019
10292
  } catch (e) {
10020
10293
  catchError(buildCtx.diagnostics, e);
10021
10294
  }
10022
10295
  };
10023
- const MAX_CSS_INLINE_SIZE = 3 * 1024;
10296
+ const MAX_CSS_INLINE_SIZE = 3072;
10024
10297
  //#endregion
10025
10298
  //#region src/compiler/transformers/component-ssr/ssr-runtime-cmp-meta.ts
10026
10299
  const addHydrateRuntimeCmpMeta = (classMembers, cmp, buildCtx) => {
10027
10300
  const compactMeta = formatComponentRuntimeMeta(cmp, true);
10028
- const staticMember = createStaticGetter("cmpMeta", convertValueToLiteral({
10301
+ const cmpMeta = {
10029
10302
  $flags$: compactMeta[0],
10030
10303
  $tagName$: compactMeta[1],
10031
10304
  $members$: compactMeta[2],
10032
10305
  $listeners$: compactMeta[3],
10033
10306
  $lazyBundleId$: fakeBundleIds(cmp),
10034
10307
  $attrsToReflect$: getHydrateAttrsToReflect(cmp)
10035
- }));
10308
+ };
10309
+ const staticMember = createStaticGetter("cmpMeta", convertValueToLiteral(cmpMeta));
10036
10310
  addStaticStyleGetterWithinClass(classMembers, cmp, buildCtx);
10037
10311
  classMembers.push(staticMember);
10038
10312
  };
@@ -10158,7 +10432,7 @@ const getSsrBuildConditionals = (config, cmps) => {
10158
10432
  */
10159
10433
  const bundleSsrFactory = async (config, compilerCtx, buildCtx, appFactoryEntryCode) => {
10160
10434
  try {
10161
- return await bundleOutput(config, compilerCtx, buildCtx, {
10435
+ const bundleOpts = {
10162
10436
  id: "ssr",
10163
10437
  platform: "ssr",
10164
10438
  conditionals: getSsrBuildConditionals(config, buildCtx.components),
@@ -10166,7 +10440,8 @@ const bundleSsrFactory = async (config, compilerCtx, buildCtx, appFactoryEntryCo
10166
10440
  codeSplitting: false,
10167
10441
  inputs: { "@stencil/core/runtime/server/ssr-factory": "@stencil/core/runtime/server/ssr-factory" },
10168
10442
  loader: { "@stencil/core/runtime/server/ssr-factory": appFactoryEntryCode }
10169
- });
10443
+ };
10444
+ return await bundleOutput(config, compilerCtx, buildCtx, bundleOpts);
10170
10445
  } catch (e) {
10171
10446
  if (!buildCtx.hasError && isRolldownError(e)) loadRolldownDiagnostics(config, compilerCtx, buildCtx, e);
10172
10447
  }
@@ -10360,7 +10635,8 @@ const SSR_FACTORY_OUTRO = `
10360
10635
  * @returns The updated component metadata array.
10361
10636
  */
10362
10637
  const updateSsrComponents = async (cmps) => {
10363
- return sortBy(await Promise.all(cmps.map(updateSsrComponent)), (c) => c.cmp.componentClassName);
10638
+ const ssrCmps = await Promise.all(cmps.map(updateSsrComponent));
10639
+ return sortBy(ssrCmps, (c) => c.cmp.componentClassName);
10364
10640
  };
10365
10641
  const updateSsrComponent = async (cmp) => {
10366
10642
  const cmpData = {
@@ -10480,7 +10756,8 @@ const writeSsrOutput = async (config, compilerCtx, buildCtx, outputTarget, rolld
10480
10756
  }));
10481
10757
  };
10482
10758
  const copySsrRunnerDts = async (config, compilerCtx, hydrateAppDirPath) => {
10483
- const srcSsrDir = join$2(join$2(config.sys.getCompilerExecutingPath(), "..", ".."), "runtime", "server", "runner.d.mts");
10759
+ const packageDir = join$2(config.sys.getCompilerExecutingPath(), "..", "..");
10760
+ const srcSsrDir = join$2(packageDir, "runtime", "server", "runner.d.mts");
10484
10761
  const runnerDtsDestPath = join$2(hydrateAppDirPath, "index.d.ts");
10485
10762
  await compilerCtx.fs.copyFile(srcSsrDir, runnerDtsDestPath);
10486
10763
  };
@@ -10497,11 +10774,12 @@ const copySsrRunnerDts = async (config, compilerCtx, hydrateAppDirPath) => {
10497
10774
  */
10498
10775
  const buildSsrAppFor = async (format, rolldownBuild, config, compilerCtx, buildCtx, outputTargets) => {
10499
10776
  const file = format === "esm" ? "index.js" : "index.cjs";
10500
- await writeSsrOutputs(config, compilerCtx, buildCtx, outputTargets, await rolldownBuild.generate({
10777
+ const rolldownOutput = await rolldownBuild.generate({
10501
10778
  banner: generatePreamble(config),
10502
10779
  format,
10503
10780
  file
10504
- }));
10781
+ });
10782
+ await writeSsrOutputs(config, compilerCtx, buildCtx, outputTargets, rolldownOutput);
10505
10783
  };
10506
10784
  /**
10507
10785
  * Generate and build the SSR app and then write it to disk
@@ -10516,7 +10794,7 @@ const generateSsrApp = async (config, compilerCtx, buildCtx, outputTargets) => {
10516
10794
  const packageDir = join$2(config.sys.getCompilerExecutingPath(), "..", "..");
10517
10795
  const input = join$2(packageDir, "runtime", "server", "runner.mjs");
10518
10796
  const appData = join$2(packageDir, "runtime", "app-data", "index.js");
10519
- const rolldownAppBuild = await rolldown({
10797
+ const rolldownOptions = {
10520
10798
  ...config.rolldownConfig,
10521
10799
  external: ["node:stream"],
10522
10800
  input,
@@ -10551,7 +10829,8 @@ const generateSsrApp = async (config, compilerCtx, buildCtx, outputTargets) => {
10551
10829
  treeshake: false,
10552
10830
  onwarn: createOnWarnFn(buildCtx.diagnostics),
10553
10831
  checks: { pluginTimings: config.logLevel === "debug" }
10554
- });
10832
+ };
10833
+ const rolldownAppBuild = await rolldown(rolldownOptions);
10555
10834
  const buildPromises = [buildSsrAppFor("esm", rolldownAppBuild, config, compilerCtx, buildCtx, outputTargets)];
10556
10835
  if (outputTargets.some((o) => o.cjs)) buildPromises.push(buildSsrAppFor("cjs", rolldownAppBuild, config, compilerCtx, buildCtx, outputTargets));
10557
10836
  await Promise.all(buildPromises);
@@ -10561,7 +10840,8 @@ const generateSsrApp = async (config, compilerCtx, buildCtx, outputTargets) => {
10561
10840
  };
10562
10841
  const generateSsrFactory = async (config, compilerCtx, buildCtx) => {
10563
10842
  if (!buildCtx.hasError) try {
10564
- const rolldownFactoryBuild = await bundleSsrFactory(config, compilerCtx, buildCtx, await generateSsrFactoryEntry(buildCtx));
10843
+ const appFactoryEntryCode = await generateSsrFactoryEntry(buildCtx);
10844
+ const rolldownFactoryBuild = await bundleSsrFactory(config, compilerCtx, buildCtx, appFactoryEntryCode);
10565
10845
  if (rolldownFactoryBuild != null) {
10566
10846
  const rolldownOutput = await rolldownFactoryBuild.generate({
10567
10847
  format: "cjs",
@@ -10650,7 +10930,7 @@ const generateSsrWasmApp = async (config, compilerCtx, buildCtx, outputTargets)
10650
10930
  const packageDir = join$2(config.sys.getCompilerExecutingPath(), "..", "..");
10651
10931
  const input = join$2(packageDir, "runtime", "server", "runner.mjs");
10652
10932
  const appData = join$2(packageDir, "runtime", "app-data", "index.js");
10653
- const rolldownOutput = await (await rolldown({
10933
+ const rolldownOptions = {
10654
10934
  ...config.rolldownConfig,
10655
10935
  external: [],
10656
10936
  input,
@@ -10681,7 +10961,8 @@ const generateSsrWasmApp = async (config, compilerCtx, buildCtx, outputTargets)
10681
10961
  transform: { target: "es2020" },
10682
10962
  onwarn: createOnWarnFn(buildCtx.diagnostics),
10683
10963
  checks: { pluginTimings: config.logLevel === "debug" }
10684
- })).generate({
10964
+ };
10965
+ const rolldownOutput = await (await rolldown(rolldownOptions)).generate({
10685
10966
  banner: generatePreamble(config) + SSR_WASM_TIMER_POLYFILL,
10686
10967
  outro: SSR_WASM_OUTRO,
10687
10968
  format: "iife",
@@ -10914,7 +11195,8 @@ const createComponentMetadataProxy = (compilerMeta) => {
10914
11195
  * @returns the generated call expression
10915
11196
  */
10916
11197
  const createClassMetadataProxy = (compilerMeta, clazz) => {
10917
- const literalMeta = convertValueToLiteral(formatComponentRuntimeMeta(compilerMeta, true));
11198
+ const compactMeta = formatComponentRuntimeMeta(compilerMeta, true);
11199
+ const literalMeta = convertValueToLiteral(compactMeta);
10918
11200
  return ts.factory.createCallExpression(ts.factory.createIdentifier(PROXY_CUSTOM_ELEMENT), [], [clazz, literalMeta]);
10919
11201
  };
10920
11202
  //#endregion
@@ -10949,7 +11231,8 @@ const proxyCustomElement = (compilerCtx, transformOpts) => {
10949
11231
  for (const [stmtIndex, stmt] of tsSourceFile.statements.entries()) if (ts.isVariableStatement(stmt)) for (const [declarationIndex, declaration] of stmt.declarationList.declarations.entries()) {
10950
11232
  if (declaration.name.getText() !== principalComponent.componentClassName) continue;
10951
11233
  if (!ts.isClassExpression(declaration.initializer)) continue;
10952
- const proxyCreationCall = createClassMetadataProxy(principalComponent, ts.factory.updateClassExpression(declaration.initializer, ts.getModifiers(declaration.initializer), ts.factory.createIdentifier(principalComponent.componentClassName), declaration.initializer.typeParameters, declaration.initializer.heritageClauses, declaration.initializer.members));
11234
+ const renamedClassExpression = ts.factory.updateClassExpression(declaration.initializer, ts.getModifiers(declaration.initializer), ts.factory.createIdentifier(principalComponent.componentClassName), declaration.initializer.typeParameters, declaration.initializer.heritageClauses, declaration.initializer.members);
11235
+ const proxyCreationCall = createClassMetadataProxy(principalComponent, renamedClassExpression);
10953
11236
  ts.addSyntheticLeadingComment(proxyCreationCall, ts.SyntaxKind.MultiLineCommentTrivia, "@__PURE__", false);
10954
11237
  const proxiedComponentDeclaration = ts.factory.updateVariableDeclaration(declaration, declaration.name, declaration.exclamationToken, declaration.type, proxyCreationCall);
10955
11238
  const updatedDeclarationList = ts.factory.updateVariableDeclarationList(stmt.declarationList, [
@@ -11113,11 +11396,12 @@ function createStatesAddCall(memberName, stateName) {
11113
11396
  const updateNativeConstructor = (classMembers, moduleFile, cmp, classNode) => {
11114
11397
  if (cmp.isPlain) return;
11115
11398
  const cstrMethodArgs = [ts.factory.createParameterDeclaration(void 0, void 0, ts.factory.createIdentifier("registerHost"))];
11116
- updateConstructor(classNode, classMembers, [
11399
+ const nativeCstrStatements = [
11117
11400
  ...nativeInit(cmp),
11118
11401
  ...addCreateEvents(moduleFile, cmp),
11119
11402
  ...createNativeAttachInternalsBinding(cmp)
11120
- ], cstrMethodArgs, cmp.doesExtend);
11403
+ ];
11404
+ updateConstructor(classNode, classMembers, nativeCstrStatements, cstrMethodArgs, cmp.doesExtend);
11121
11405
  };
11122
11406
  /**
11123
11407
  * Generates a series of expression statements used to help initialize a Stencil component
@@ -11171,8 +11455,10 @@ const addNativeComponentMeta = (classMembers, cmp) => {
11171
11455
  //#endregion
11172
11456
  //#region src/compiler/transformers/component-native/native-static-style.ts
11173
11457
  const addNativeStaticStyle = (classMembers, cmp, buildCtx) => {
11174
- if (Array.isArray(cmp.styles) && cmp.styles.length > 0) if (cmp.styles.length > 1 || cmp.styles.length === 1 && cmp.styles[0].modeName !== "$") addMultipleModeStyleGetter(classMembers, cmp, cmp.styles, buildCtx);
11175
- else addSingleStyleGetter(classMembers, cmp, cmp.styles[0], buildCtx);
11458
+ if (Array.isArray(cmp.styles) && cmp.styles.length > 0) {
11459
+ if (cmp.styles.length > 1 || cmp.styles.length === 1 && cmp.styles[0].modeName !== "$") addMultipleModeStyleGetter(classMembers, cmp, cmp.styles, buildCtx);
11460
+ else addSingleStyleGetter(classMembers, cmp, cmp.styles[0], buildCtx);
11461
+ }
11176
11462
  };
11177
11463
  const addMultipleModeStyleGetter = (classMembers, cmp, styles, buildCtx) => {
11178
11464
  const styleModes = [];
@@ -11311,7 +11597,8 @@ const updateNativeHostComponentHeritageClauses = (classNode, moduleFile) => {
11311
11597
  */
11312
11598
  const updateNativeBaseClass = (node, moduleFile) => {
11313
11599
  const withHeritageClauses = updateNativeHostComponentHeritageClauses(node, moduleFile);
11314
- const membersWithCtor = updateConstructor(withHeritageClauses, removeStaticMetaProperties(withHeritageClauses), [], void 0, false);
11600
+ const members = removeStaticMetaProperties(withHeritageClauses);
11601
+ const membersWithCtor = updateConstructor(withHeritageClauses, members, [], void 0, false);
11315
11602
  return ts.factory.updateClassDeclaration(withHeritageClauses, withHeritageClauses.modifiers, withHeritageClauses.name, withHeritageClauses.typeParameters, withHeritageClauses.heritageClauses, membersWithCtor);
11316
11603
  };
11317
11604
  /**
@@ -11419,9 +11706,11 @@ const generateLoaderModule = (components, outputTarget, relativeAssetPath) => {
11419
11706
  const autoStart = typeof autoLoaderConfig === "object" ? autoLoaderConfig.autoStart !== false : true;
11420
11707
  const tagsList = components.map((cmp) => `'${cmp.tagName}'`).join(", ");
11421
11708
  const switchCases = components.map((cmp) => ` case '${cmp.tagName}': module = await import('./${cmp.tagName}.js'); break;`).join("\n");
11709
+ const assetPathImport = relativeAssetPath ? `import { setAssetPath } from '${STENCIL_INTERNAL_STANDALONE_CLIENT_PLATFORM_ID}';\n` : "";
11710
+ const assetPathInit = relativeAssetPath ? `setAssetPath(new URL('${relativeAssetPath}', String(import.meta.url)).href);\n` : "";
11422
11711
  return `
11423
11712
  import { transformTag, getRegistry } from '${STENCIL_INTERNAL_STANDALONE_CLIENT_PLATFORM_ID}';
11424
- ${relativeAssetPath ? `import { setAssetPath } from '${STENCIL_INTERNAL_STANDALONE_CLIENT_PLATFORM_ID}';\n` : ""}${relativeAssetPath ? `setAssetPath(new URL('${relativeAssetPath}', String(import.meta.url)).href);\n` : ""}
11713
+ ${assetPathImport}${assetPathInit}
11425
11714
 
11426
11715
  /**
11427
11716
  * Tag names built at compile time.
@@ -11455,13 +11744,13 @@ let observer;
11455
11744
  /**
11456
11745
  * Scan a root element for undefined custom elements and load them.
11457
11746
  *
11458
- * Before any modules are imported we do two things to guarantee the documented
11459
- * Stencil lifecycle ordering (componentWillLoad top-down, componentDidLoad
11460
- * bottom-up) regardless of module-load race conditions:
11747
+ * Before any modules are imported we do 3 things to guarantee the documented
11748
+ * Stencil lifecycle ordering (connectedCallback/componentWillLoad top-down,
11749
+ * componentDidLoad bottom-up) regardless of which tag's chunk happens to resolve first:
11461
11750
  *
11462
- * 1. Pre-mark every not-yet-upgraded Stencil element with empty \`s-p\`/\`s-rc\`
11463
- * arrays so the runtime's connectedCallback ancestor walk can always find a
11464
- * parent element even before it has been upgraded.
11751
+ * 1. Pre-mark every not-yet-upgraded Stencil element with empty \`s-p\`/\`s-rc\`/\`s-pc\`
11752
+ * arrays so the runtime's connectedCallback ancestor walk can always find a parent
11753
+ * element even before it has been upgraded (see \`connected-callback.ts\`).
11465
11754
  *
11466
11755
  * 2. For every child Stencil element, push a Promise into its nearest Stencil
11467
11756
  * ancestor's \`s-p\` array. That Promise resolves only after the child's full
@@ -11470,6 +11759,15 @@ let observer;
11470
11759
  * descendants are ready - even when a descendant's module loads *after* the
11471
11760
  * ancestor has already started rendering.
11472
11761
  *
11762
+ * 3. Likewise, push a Promise into the ancestor's \`s-pc\` array that resolves once the
11763
+ * child's real \`connectedCallback\` has fired (\`s-fc\`). Without this, an ancestor
11764
+ * whose own module resolves before an unconnected child's would check \`s-pc\` (see
11765
+ * \`scheduleUpdate\` in \`update-component.ts\`) before that child ever got a chance to
11766
+ * register itself via \`attachToAncestor\` - since a not-yet-defined child doesn't
11767
+ * connect (and self-register) until its own module import resolves. Pre-registering
11768
+ * here means the ancestor's \`componentWillLoad\` always waits for it, however long
11769
+ * that import takes.
11770
+ *
11473
11771
  * @param root - The root element to scan
11474
11772
  */
11475
11773
  async function load(root) {
@@ -11482,6 +11780,7 @@ async function load(root) {
11482
11780
  if (lookup[rootTag]) {
11483
11781
  if (!root['s-p']) root['s-p'] = [];
11484
11782
  if (!root['s-rc']) root['s-rc'] = [];
11783
+ if (!root['s-pc']) root['s-pc'] = [];
11485
11784
  if (!defined.has(rootTag)) pending.add(rootTag);
11486
11785
  elements.push(root);
11487
11786
  }
@@ -11493,6 +11792,7 @@ async function load(root) {
11493
11792
  if (lookup[tag]) {
11494
11793
  if (!el['s-p']) el['s-p'] = [];
11495
11794
  if (!el['s-rc']) el['s-rc'] = [];
11795
+ if (!el['s-pc']) el['s-pc'] = [];
11496
11796
  if (!defined.has(tag)) pending.add(tag);
11497
11797
  elements.push(el);
11498
11798
  }
@@ -11515,6 +11815,11 @@ async function load(root) {
11515
11815
  ancestor['s-p'].push(
11516
11816
  reg.whenDefined(tag).then(() => el['s-rp'])
11517
11817
  );
11818
+ // Same idea, but resolving once the child's real connectedCallback has fired
11819
+ // rather than once its full initial lifecycle has completed.
11820
+ ancestor['s-pc'].push(
11821
+ reg.whenDefined(tag).then(() => el['s-fc'])
11822
+ );
11518
11823
  break;
11519
11824
  }
11520
11825
  ancestor = ancestor.parentElement;
@@ -12047,11 +12352,12 @@ const getTypescriptPathFromUrl = (config, tsExecutingUrl, url) => {
12047
12352
  const tsBaseUrl = new URL("..", tsExecutingUrl).href;
12048
12353
  if (url.startsWith(tsBaseUrl)) {
12049
12354
  const tsFilePath = url.replace(tsBaseUrl, "/");
12050
- return normalizePath(config.sys.getLocalModulePath({
12355
+ const tsNodePath = config.sys.getLocalModulePath({
12051
12356
  rootDir: config.rootDir,
12052
12357
  moduleId: "@stencil/core",
12053
12358
  path: tsFilePath
12054
- }));
12359
+ });
12360
+ return normalizePath(tsNodePath);
12055
12361
  }
12056
12362
  return url;
12057
12363
  };
@@ -12094,9 +12400,25 @@ const tsResolveModuleNamePackageJsonPath = (config, compilerCtx, moduleName, con
12094
12400
  };
12095
12401
  //#endregion
12096
12402
  //#region src/compiler/transformers/static-to-meta/vdom.ts
12097
- const gatherVdomMeta = (m, args) => {
12403
+ /**
12404
+ * Attempt to resolve an expression to a statically-known string value.
12405
+ * Handles plain string literals directly. For anything else, falls back to the type checker.
12406
+ *
12407
+ * @param expr the expression to resolve
12408
+ * @param typeChecker the type checker for the program being compiled, if available
12409
+ * @returns the statically-known string value, or `undefined` if it can't be determined
12410
+ */
12411
+ const resolveStaticStringValue = (expr, typeChecker) => {
12412
+ if (ts.isStringLiteralLike(expr)) return expr.text;
12413
+ if (typeChecker) {
12414
+ const type = typeChecker.getTypeAtLocation(expr);
12415
+ if (type.isStringLiteral()) return type.value;
12416
+ }
12417
+ };
12418
+ const gatherVdomMeta = (m, args, typeChecker) => {
12098
12419
  m.hasVdomRender = true;
12099
12420
  const hTag = args[0];
12421
+ const isSlotTag = ts.isStringLiteral(hTag) && hTag.text === "slot";
12100
12422
  if (!ts.isStringLiteral(hTag) && (!ts.isIdentifier(hTag) || hTag.text !== "Host")) m.hasVdomFunctional = true;
12101
12423
  if (args.length > 1) {
12102
12424
  const objectLiteral = args[1];
@@ -12109,32 +12431,46 @@ const gatherVdomMeta = (m, args) => {
12109
12431
  m.hasVdomRef = true;
12110
12432
  m.hasVdomStyle = true;
12111
12433
  m.hasVdomXlink = true;
12112
- } else if (ts.isObjectLiteralExpression(objectLiteral)) objectLiteral.properties.forEach((prop) => {
12113
- m.hasVdomAttribute = true;
12114
- if (ts.isSpreadAssignment(prop) || ts.isComputedPropertyName(prop.name)) {
12115
- m.hasVdomClass = true;
12116
- m.hasVdomKey = true;
12117
- m.hasVdomListener = true;
12118
- m.hasVdomPropOrAttr = true;
12119
- m.hasVdomRef = true;
12120
- m.hasVdomStyle = true;
12121
- m.hasVdomXlink = true;
12122
- } else if (prop.name && prop.name.text && prop.name.text.length > 0) {
12123
- const attrName = prop.name.text;
12124
- if (attrName === "key") m.hasVdomKey = true;
12125
- else if (attrName === "ref") m.hasVdomRef = true;
12126
- else if (attrName === "class" || attrName === "className") m.hasVdomClass = true;
12127
- else if (attrName === "style") m.hasVdomStyle = true;
12128
- else if (/^on(-|[A-Z])/.test(attrName)) m.hasVdomListener = true;
12129
- else if (attrName.startsWith("xlink")) {
12130
- m.hasVdomXlink = true;
12434
+ } else if (ts.isObjectLiteralExpression(objectLiteral)) {
12435
+ let slotName;
12436
+ let hasDynamicSlotName = false;
12437
+ objectLiteral.properties.forEach((prop) => {
12438
+ m.hasVdomAttribute = true;
12439
+ if (ts.isSpreadAssignment(prop) || ts.isComputedPropertyName(prop.name)) {
12440
+ m.hasVdomClass = true;
12441
+ m.hasVdomKey = true;
12442
+ m.hasVdomListener = true;
12131
12443
  m.hasVdomPropOrAttr = true;
12132
- } else m.hasVdomPropOrAttr = true;
12133
- if (attrName === "part" && ts.isPropertyAssignment(prop) && ts.isStringLiteral(prop.initializer)) m.htmlParts.push(...prop.initializer.text.toLowerCase().split(" ").filter((part) => part.length > 0));
12134
- m.htmlAttrNames.push(attrName);
12135
- }
12136
- });
12137
- }
12444
+ m.hasVdomRef = true;
12445
+ m.hasVdomStyle = true;
12446
+ m.hasVdomXlink = true;
12447
+ hasDynamicSlotName = isSlotTag || hasDynamicSlotName;
12448
+ } else if (prop.name && prop.name.text && prop.name.text.length > 0) {
12449
+ const attrName = prop.name.text;
12450
+ if (attrName === "key") m.hasVdomKey = true;
12451
+ else if (attrName === "ref") m.hasVdomRef = true;
12452
+ else if (attrName === "class" || attrName === "className") m.hasVdomClass = true;
12453
+ else if (attrName === "style") m.hasVdomStyle = true;
12454
+ else if (/^on(-|[A-Z])/.test(attrName)) m.hasVdomListener = true;
12455
+ else if (attrName.startsWith("xlink")) {
12456
+ m.hasVdomXlink = true;
12457
+ m.hasVdomPropOrAttr = true;
12458
+ } else m.hasVdomPropOrAttr = true;
12459
+ if (attrName === "part" && ts.isPropertyAssignment(prop)) {
12460
+ const partValue = resolveStaticStringValue(prop.initializer, typeChecker);
12461
+ if (partValue !== void 0) m.htmlParts.push(...partValue.split(" ").filter((part) => part.length > 0));
12462
+ }
12463
+ if (isSlotTag && attrName === "name" && ts.isPropertyAssignment(prop)) {
12464
+ const resolvedSlotName = resolveStaticStringValue(prop.initializer, typeChecker);
12465
+ if (resolvedSlotName !== void 0) slotName = resolvedSlotName;
12466
+ else hasDynamicSlotName = true;
12467
+ }
12468
+ m.htmlAttrNames.push(attrName);
12469
+ }
12470
+ });
12471
+ if (isSlotTag && !hasDynamicSlotName) m.htmlSlots.push(slotName ?? "");
12472
+ } else if (isSlotTag) m.htmlSlots.push("");
12473
+ } else if (isSlotTag) m.htmlSlots.push("");
12138
12474
  if (!m.hasVdomText) for (let i = 2; i < args.length; i++) {
12139
12475
  const arg = args[i];
12140
12476
  if (!ts.isCallExpression(arg) || !ts.isIdentifier(arg.expression) || arg.expression.text !== "h") {
@@ -12172,10 +12508,10 @@ const visitCallExpressionArgs = (m, callExpressionName, args, typeChecker) => {
12172
12508
  const fnName = callExpressionName.escapedText;
12173
12509
  if (fnName === "h" || fnName === "__stencil_h" || fnName === "createElement") {
12174
12510
  visitCallExpressionArg(m, args[0], typeChecker);
12175
- if (fnName === "h" || fnName === "__stencil_h") gatherVdomMeta(m, args);
12511
+ if (fnName === "h" || fnName === "__stencil_h") gatherVdomMeta(m, args, typeChecker);
12176
12512
  } else if (fnName === "jsx" || fnName === "jsxs" || fnName === "_jsx" || fnName === "_jsxs") {
12177
12513
  visitCallExpressionArg(m, args[0], typeChecker);
12178
- gatherVdomMeta(m, args);
12514
+ gatherVdomMeta(m, args, typeChecker);
12179
12515
  if (args.length > 2 && args[2]) m.hasVdomKey = true;
12180
12516
  } else if (args.length > 1 && fnName === "createElementNS") visitCallExpressionArg(m, args[1], typeChecker);
12181
12517
  else if (fnName === "require" && args.length > 0 && m.originalImports) {
@@ -12231,7 +12567,8 @@ const resolveFunctionalComponentDep = (m, identifier, typeChecker) => {
12231
12567
  * @returns the updated typescript class declaration
12232
12568
  */
12233
12569
  const addComponentMetaStatic = (cmpNode, cmpMeta) => {
12234
- const cmpMetaStaticProp = createStaticGetter("COMPILER_META", convertValueToLiteral(getPublicCompilerMeta(cmpMeta)));
12570
+ const publicCompilerMeta = getPublicCompilerMeta(cmpMeta);
12571
+ const cmpMetaStaticProp = createStaticGetter("COMPILER_META", convertValueToLiteral(publicCompilerMeta));
12235
12572
  const classMembers = [...cmpNode.members, cmpMetaStaticProp];
12236
12573
  return ts.factory.updateClassDeclaration(cmpNode, retrieveModifierLike(cmpNode), cmpNode.name, cmpNode.typeParameters, cmpNode.heritageClauses, classMembers);
12237
12574
  };
@@ -12279,7 +12616,7 @@ const setComponentBuildConditionals = (cmpMeta) => {
12279
12616
  cmpMeta.hasStyle = true;
12280
12617
  cmpMeta.hasMode = cmpMeta.styles.some((s) => s.modeName !== "$");
12281
12618
  }
12282
- cmpMeta.hasLifecycle = cmpMeta.hasComponentWillLoadFn || cmpMeta.hasComponentDidLoadFn || cmpMeta.hasComponentShouldUpdateFn || cmpMeta.hasComponentWillUpdateFn || cmpMeta.hasComponentDidUpdateFn || cmpMeta.hasComponentWillRenderFn || cmpMeta.hasComponentDidRenderFn;
12619
+ cmpMeta.hasLifecycle = cmpMeta.hasComponentWillLoadFn || cmpMeta.hasComponentDidLoadFn || cmpMeta.hasComponentShouldUpdateFn || cmpMeta.hasComponentWillUpdateFn || cmpMeta.hasComponentDidUpdateFn || cmpMeta.hasComponentWillRenderFn || cmpMeta.hasComponentDidRenderFn || cmpMeta.hasConnectedCallbackFn || cmpMeta.hasDisconnectedCallbackFn;
12283
12620
  cmpMeta.isPlain = !cmpMeta.hasMember && !cmpMeta.hasStyle && !cmpMeta.hasLifecycle && !cmpMeta.hasListener && !cmpMeta.hasVdomRender;
12284
12621
  if (cmpMeta.patches) {
12285
12622
  cmpMeta.hasPatchAll = !!cmpMeta.patches.all;
@@ -12407,7 +12744,8 @@ const getDecoratorParameter = (arg, typeChecker, diagnostics, errorNode) => {
12407
12744
  */
12408
12745
  const resolveVariableValue = (node, typeChecker, diagnostics, errorNode) => {
12409
12746
  if (ts.isIdentifier(node)) {
12410
- const symbol = typeChecker.getSymbolAtLocation(node);
12747
+ let symbol = typeChecker.getSymbolAtLocation(node);
12748
+ if (symbol && symbol.flags & ts.SymbolFlags.Alias) symbol = typeChecker.getAliasedSymbol(symbol);
12411
12749
  if (!symbol || !symbol.valueDeclaration) {
12412
12750
  const err = buildError(diagnostics);
12413
12751
  err.messageText = `resolveVar() cannot resolve the value of "${node.text}" at compile time. Only const variables and object properties with string literal values are supported.`;
@@ -12607,8 +12945,10 @@ function parseCustomStatesFromDecorator(decorator, typeChecker) {
12607
12945
  //#region src/compiler/transformers/decorators-to-static/style-to-static.ts
12608
12946
  const styleToStatic = (newMembers, componentOptions) => {
12609
12947
  const defaultModeStyles = [];
12610
- if (componentOptions.styleUrls) if (Array.isArray(componentOptions.styleUrls)) defaultModeStyles.push(...normalizeStyleUrl(componentOptions.styleUrls));
12611
- else defaultModeStyles.push(...normalizeStyleUrl(componentOptions.styleUrls["$"]));
12948
+ if (componentOptions.styleUrls) {
12949
+ if (Array.isArray(componentOptions.styleUrls)) defaultModeStyles.push(...normalizeStyleUrl(componentOptions.styleUrls));
12950
+ else defaultModeStyles.push(...normalizeStyleUrl(componentOptions.styleUrls["$"]));
12951
+ }
12612
12952
  if (componentOptions.styleUrl) defaultModeStyles.push(...normalizeStyleUrl(componentOptions.styleUrl));
12613
12953
  let styleUrls = {};
12614
12954
  if (componentOptions.styleUrls && !Array.isArray(componentOptions.styleUrls)) styleUrls = normalizeStyleUrls(componentOptions.styleUrls);
@@ -12616,7 +12956,8 @@ const styleToStatic = (newMembers, componentOptions) => {
12616
12956
  if (Object.keys(styleUrls).length > 0) {
12617
12957
  const originalStyleUrls = convertValueToLiteral(styleUrls);
12618
12958
  newMembers.push(createStaticGetter("originalStyleUrls", originalStyleUrls));
12619
- const normalizedStyleExp = convertValueToLiteral(normalizeExtension(styleUrls));
12959
+ const norlizedStyleExt = normalizeExtension(styleUrls);
12960
+ const normalizedStyleExp = convertValueToLiteral(norlizedStyleExt);
12620
12961
  newMembers.push(createStaticGetter("styleUrls", normalizedStyleExp));
12621
12962
  }
12622
12963
  if (componentOptions.globalStyleUrl) newMembers.push(createStaticGetter("originalGlobalStyleUrl", convertValueToLiteral(componentOptions.globalStyleUrl)));
@@ -12645,7 +12986,10 @@ const normalizeExtension = (styleUrls) => {
12645
12986
  return compilerStyleUrls;
12646
12987
  };
12647
12988
  const useCss = (stylePath) => {
12648
- return join$2(dirname$1(stylePath), basename$1(stylePath, extname(stylePath)) + ".css");
12989
+ const sourceFileDir = dirname$1(stylePath);
12990
+ const sourceFileExt = extname(stylePath);
12991
+ const sourceFileName = basename$1(stylePath, sourceFileExt);
12992
+ return join$2(sourceFileDir, sourceFileName + ".css");
12649
12993
  };
12650
12994
  const normalizeStyleUrls = (styleUrls) => {
12651
12995
  const compilerStyleUrls = {};
@@ -12795,6 +13139,13 @@ const validateComponent = (config, diagnostics, typeChecker, componentOptions, c
12795
13139
  }
12796
13140
  }
12797
13141
  }
13142
+ const modeError = validateComponentModes(config.modes, componentOptions);
13143
+ if (modeError) {
13144
+ const err = buildError(diagnostics);
13145
+ err.messageText = modeError.message;
13146
+ augmentDiagnosticWithNode(err, findTagNode(modeError.propName, componentDecorator));
13147
+ return false;
13148
+ }
12798
13149
  const constructor = cmpNode.members.find(ts.isConstructorDeclaration);
12799
13150
  if (constructor && constructor.parameters.length > 0) {
12800
13151
  const err = buildError(diagnostics);
@@ -12832,7 +13183,8 @@ const validateComponent = (config, diagnostics, typeChecker, componentOptions, c
12832
13183
  err.messageText = `To allow efficient bundling, modules using @Component() can only have a single export which is the component class itself.
12833
13184
  Any other exports should be moved to a separate file.
12834
13185
  For further information check out: https://stenciljs.com/docs/module-bundling`;
12835
- augmentDiagnosticWithNode(err, symbol.valueDeclaration ? symbol.valueDeclaration : symbol.declarations[0]);
13186
+ const errorNode = symbol.valueDeclaration ? symbol.valueDeclaration : symbol.declarations[0];
13187
+ augmentDiagnosticWithNode(err, errorNode);
12836
13188
  });
12837
13189
  if (nonTypeExports.length > 0) return false;
12838
13190
  }
@@ -13009,7 +13361,7 @@ const validateEventName = (config, diagnostics, node, eventName) => {
13009
13361
  augmentDiagnosticWithNode(warn, node);
13010
13362
  return;
13011
13363
  }
13012
- if (!config.suppressReservedEventNameWarnings && DOM_EVENT_NAMES.has(eventName.toLowerCase())) {
13364
+ if (!config.compat?.suppressEventNameWarnings && DOM_EVENT_NAMES.has(eventName.toLowerCase())) {
13013
13365
  const diagnostic = buildWarn(diagnostics);
13014
13366
  diagnostic.messageText = `The event name conflicts with the "${eventName}" native DOM event name.`;
13015
13367
  augmentDiagnosticWithNode(diagnostic, node);
@@ -13308,7 +13660,8 @@ var ImportAliasMap = class extends Map {
13308
13660
  //#endregion
13309
13661
  //#region src/compiler/transformers/decorators-to-static/listen-decorator.ts
13310
13662
  const listenDecoratorsToStatic = (diagnostics, typeChecker, decoratedMembers, newMembers, decoratorName) => {
13311
- const flatListeners = flatOne(decoratedMembers.filter(ts.isMethodDeclaration).map((method) => parseListenDecorators(diagnostics, typeChecker, method, decoratorName)));
13663
+ const listeners = decoratedMembers.filter(ts.isMethodDeclaration).map((method) => parseListenDecorators(diagnostics, typeChecker, method, decoratorName));
13664
+ const flatListeners = flatOne(listeners);
13312
13665
  if (flatListeners.length > 0) newMembers.push(createStaticGetter("listeners", convertValueToLiteral(flatListeners)));
13313
13666
  };
13314
13667
  const parseListenDecorators = (diagnostics, typeChecker, method, decoratorName) => {
@@ -13342,7 +13695,7 @@ const parseListener = (eventName, opts = {}, methodName) => {
13342
13695
  passive: typeof opts.passive === "boolean" ? opts.passive : PASSIVE_TRUE_DEFAULTS.has(rawEventName.toLowerCase())
13343
13696
  };
13344
13697
  };
13345
- const PASSIVE_TRUE_DEFAULTS = new Set([
13698
+ const PASSIVE_TRUE_DEFAULTS = /* @__PURE__ */ new Set([
13346
13699
  "dragstart",
13347
13700
  "drag",
13348
13701
  "dragend",
@@ -13391,7 +13744,7 @@ const PASSIVE_TRUE_DEFAULTS = new Set([
13391
13744
  * @param node the TypeScript AST node at which the class member is defined
13392
13745
  */
13393
13746
  const validatePublicName = (config, diagnostics, memberName, decorator, memberType, node) => {
13394
- if (config.suppressReservedPublicNameWarnings) return;
13747
+ if (config.compat?.suppressPublicNameWarnings) return;
13395
13748
  if (RESERVED_PUBLIC_MEMBERS.has(memberName.toLowerCase())) {
13396
13749
  const warn = buildWarn(diagnostics);
13397
13750
  warn.messageText = [
@@ -13802,7 +14155,8 @@ const parsePropDecorator = (config, diagnostics, typeChecker, program, prop, dec
13802
14155
  const returnExpression = (prop.body?.statements.find((st) => ts.isReturnStatement(st))).expression;
13803
14156
  if (returnExpression && ts.isLiteralExpression(returnExpression)) propMeta.defaultValue = returnExpression.getText();
13804
14157
  else if (returnExpression && ts.isPropertyAccessExpression(returnExpression)) {
13805
- const foundProp = findGetProp(returnExpression.name.getText(), newMembers);
14158
+ const nameToFind = returnExpression.name.getText();
14159
+ const foundProp = findGetProp(nameToFind, newMembers);
13806
14160
  if (foundProp && foundProp.initializer) {
13807
14161
  propMeta.defaultValue = resolveInitializerText(foundProp.initializer, typeChecker);
13808
14162
  if (propMeta.type === "unknown") {
@@ -14090,8 +14444,10 @@ const serializeDecoratorsToStatic = (typeChecker, decoratedProps, newMembers, de
14090
14444
  return [];
14091
14445
  });
14092
14446
  const serializers = decoratedProps.filter(ts.isMethodDeclaration).flatMap((method) => parseSerializeDecorator(typeChecker, method, decoratorName, props));
14093
- if (serializers.length > 0) if (translateType === "PropSerialize") newMembers.push(createStaticGetter("serializers", convertValueToLiteral(serializers)));
14094
- else newMembers.push(createStaticGetter("deserializers", convertValueToLiteral(serializers)));
14447
+ if (serializers.length > 0) {
14448
+ if (translateType === "PropSerialize") newMembers.push(createStaticGetter("serializers", convertValueToLiteral(serializers)));
14449
+ else newMembers.push(createStaticGetter("deserializers", convertValueToLiteral(serializers)));
14450
+ }
14095
14451
  return serializers;
14096
14452
  };
14097
14453
  const parseSerializeDecorator = (typeChecker, method, decoratorName, props) => {
@@ -14147,7 +14503,8 @@ const stateDecoratorToStatic = (prop, typeChecker, decoratorName) => {
14147
14503
  //#endregion
14148
14504
  //#region src/compiler/transformers/decorators-to-static/watch-decorator.ts
14149
14505
  const watchDecoratorsToStatic = (typeChecker, decoratedProps, newMembers, decoratorName) => {
14150
- const flatWatchers = flatOne(decoratedProps.filter(ts.isMethodDeclaration).map((method) => parseWatchDecorator(typeChecker, method, decoratorName)));
14506
+ const watchers = decoratedProps.filter(ts.isMethodDeclaration).map((method) => parseWatchDecorator(typeChecker, method, decoratorName));
14507
+ const flatWatchers = flatOne(watchers);
14151
14508
  if (flatWatchers.length > 0) newMembers.push(createStaticGetter("watchers", convertValueToLiteral(flatWatchers)));
14152
14509
  };
14153
14510
  const parseWatchDecorator = (typeChecker, method, decoratorName) => {
@@ -14268,19 +14625,21 @@ const removeStencilMethodDecorators = (classMembers, diagnostics, importAliasMap
14268
14625
  return classMembers.map((member) => {
14269
14626
  const currentDecorators = retrieveTsDecorators(member);
14270
14627
  const newDecorators = filterDecorators(currentDecorators, MEMBER_DECORATORS_TO_REMOVE.map((decorator) => importAliasMap.get(decorator)));
14271
- if (currentDecorators !== newDecorators) if (ts.isMethodDeclaration(member)) return ts.factory.updateMethodDeclaration(member, [...newDecorators ?? [], ...retrieveTsModifiers(member) ?? []], member.asteriskToken, member.name, member.questionToken, member.typeParameters, member.parameters, member.type, member.body);
14272
- else if (ts.isGetAccessor(member)) return ts.factory.updateGetAccessorDeclaration(member, [...newDecorators ?? [], ...retrieveTsModifiers(member) ?? []], member.name, member.parameters, member.type, member.body);
14273
- else if (ts.isSetAccessor(member)) {
14274
- const err = buildError(diagnostics);
14275
- err.messageText = "A get accessor should be decorated before a set accessor";
14276
- augmentDiagnosticWithNode(err, member);
14277
- } else if (ts.isPropertyDeclaration(member)) {
14278
- const modifiers = retrieveTsModifiers(member);
14279
- return ts.factory.updatePropertyDeclaration(member, [...newDecorators ?? [], ...modifiers ?? []], member.name, member.questionToken, member.type, member.initializer);
14280
- } else {
14281
- const err = buildError(diagnostics);
14282
- err.messageText = "Unknown class member encountered!";
14283
- augmentDiagnosticWithNode(err, member);
14628
+ if (currentDecorators !== newDecorators) {
14629
+ if (ts.isMethodDeclaration(member)) return ts.factory.updateMethodDeclaration(member, [...newDecorators ?? [], ...retrieveTsModifiers(member) ?? []], member.asteriskToken, member.name, member.questionToken, member.typeParameters, member.parameters, member.type, member.body);
14630
+ else if (ts.isGetAccessor(member)) return ts.factory.updateGetAccessorDeclaration(member, [...newDecorators ?? [], ...retrieveTsModifiers(member) ?? []], member.name, member.parameters, member.type, member.body);
14631
+ else if (ts.isSetAccessor(member)) {
14632
+ const err = buildError(diagnostics);
14633
+ err.messageText = "A get accessor should be decorated before a set accessor";
14634
+ augmentDiagnosticWithNode(err, member);
14635
+ } else if (ts.isPropertyDeclaration(member)) {
14636
+ const modifiers = retrieveTsModifiers(member);
14637
+ return ts.factory.updatePropertyDeclaration(member, [...newDecorators ?? [], ...modifiers ?? []], member.name, member.questionToken, member.type, member.initializer);
14638
+ } else {
14639
+ const err = buildError(diagnostics);
14640
+ err.messageText = "Unknown class member encountered!";
14641
+ augmentDiagnosticWithNode(err, member);
14642
+ }
14284
14643
  }
14285
14644
  return member;
14286
14645
  });
@@ -14425,15 +14784,80 @@ const parseStaticWatchers = (staticMembers) => {
14425
14784
  });
14426
14785
  };
14427
14786
  //#endregion
14428
- //#region src/compiler/transformers/static-to-meta/class-extension.ts
14787
+ //#region src/compiler/transformers/static-to-meta/class-extension/shared.ts
14788
+ /**
14789
+ * Walks the AST looking for a class declaration, optionally by name - descends
14790
+ * into a mixin factory's wrapping function (arrow function or `function`
14791
+ * declaration) body too, since a mixin factory's class is always nested one
14792
+ * level inside it (e.g. `const Foo = (Base) => class extends Base {}`).
14793
+ * @param node the node to search from
14794
+ * @param name if given, only matches a class declaration with this name
14795
+ * @returns the found class declaration, or `undefined`
14796
+ */
14797
+ function findClassWalk(node, name) {
14798
+ if (!node) return void 0;
14799
+ if (ts.isClassDeclaration(node)) {
14800
+ if (!name || node.name?.text === name) return node;
14801
+ } else if (ts.isVariableDeclaration(node) && (!name || name === node.name?.text) && node.initializer && ts.isArrowFunction(node.initializer)) {
14802
+ let found;
14803
+ ts.forEachChild(node.initializer.body, (child) => {
14804
+ if (found) return;
14805
+ if (ts.isClassDeclaration(child)) found = child;
14806
+ });
14807
+ return found;
14808
+ }
14809
+ let found;
14810
+ ts.forEachChild(node, (child) => {
14811
+ if (found) return;
14812
+ const result = findClassWalk(child, name);
14813
+ if (result) found = result;
14814
+ });
14815
+ return found;
14816
+ }
14817
+ /**
14818
+ * Matches a top-level class/function/variable declaration by name - the three
14819
+ * shapes a mixin or base-class export can take (a plain class, a mixin
14820
+ * factory function declaration, or a mixin factory assigned to a `const`).
14821
+ * @param name the declaration name to match
14822
+ * @returns a predicate usable with `Array.prototype.find` over a source file's statements
14823
+ */
14824
+ function matchesNamedDeclaration(name) {
14825
+ return function(stmt) {
14826
+ if (ts.isClassDeclaration(stmt) && stmt.name?.text === name) return true;
14827
+ if (ts.isFunctionDeclaration(stmt) && stmt.name?.text === name) return true;
14828
+ if (ts.isVariableStatement(stmt)) {
14829
+ for (const decl of stmt.declarationList.declarations) if (ts.isIdentifier(decl.name) && decl.name.text === name) return true;
14830
+ }
14831
+ return false;
14832
+ };
14833
+ }
14429
14834
  /**
14430
- * Given two arrays of static members, return a new array containing only the
14431
- * members from the first array that are not present in the second array.
14432
- * This is used to de-dupe static members that are inherited from a parent class.
14835
+ * Finds a re-export of `className` in `sourceFile` - `export { X } from './y'` or
14836
+ * `export { X as Y } from './y'` - as used by barrel entry points (e.g. `@stencil/core`'s own
14837
+ * public `index.d.mts`, which re-exports its runtime API from `./declarations/stencil-public-runtime`
14838
+ * rather than declaring it directly).
14839
+ * @param sourceFile the (barrel) source file to scan
14840
+ * @param className the exported name to look for
14841
+ * @returns the module specifier and the name to look for in that module (the local name, before
14842
+ * any `as` aliasing), or `undefined` if no matching re-export is found
14843
+ */
14844
+ function findReExport(sourceFile, className) {
14845
+ for (const stmt of sourceFile.statements) {
14846
+ if (!ts.isExportDeclaration(stmt) || !stmt.moduleSpecifier || !ts.isStringLiteral(stmt.moduleSpecifier) || !stmt.exportClause || !ts.isNamedExports(stmt.exportClause)) continue;
14847
+ for (const element of stmt.exportClause.elements) if (element.name.text === className) return {
14848
+ moduleSpecifier: stmt.moduleSpecifier.text,
14849
+ localName: element.propertyName?.text ?? element.name.text
14850
+ };
14851
+ }
14852
+ }
14853
+ /**
14854
+ * Filters `dedupeMembers` down to entries not already present in `staticMembers`
14855
+ * (by name, or `methodName` for change handlers) - used so an extending
14856
+ * class's own members win over inherited ones.
14433
14857
  *
14434
- * @param dedupeMembers the array of static members to de-dupe
14435
- * @param staticMembers the array of static members to compare against
14436
- * @returns an array of static members that are not present in the second array
14858
+ * @param dedupeMembers the members to filter
14859
+ * @param staticMembers the members to filter against
14860
+ * @returns the filtered `dedupeMembers` array
14437
14861
  */
14438
14862
  const deDupeMembers = (dedupeMembers, staticMembers) => {
14439
14863
  return dedupeMembers.filter((s) => !staticMembers.some((d) => {
@@ -14441,22 +14865,62 @@ const deDupeMembers = (dedupeMembers, staticMembers) => {
14441
14865
  return d.name === s.name;
14442
14866
  }));
14443
14867
  };
14868
+ const ensureRelativeSpecifier = (specifier) => {
14869
+ return specifier.startsWith(".") ? specifier : `./${specifier}`;
14870
+ };
14871
+ /**
14872
+ * Re-anchors inherited members' complex-type references - recorded relative
14873
+ * to the file declaring them - so they resolve from the extending
14874
+ * component's file instead. Consumers like `components.d.ts` generation
14875
+ * always resolve a reference against the component, not the declaring class,
14876
+ * so an inherited reference from a different directory would otherwise
14877
+ * produce a broken import.
14878
+ *
14879
+ * `import` refs get their relative path rewritten; `local` refs (a type
14880
+ * declared in the extended class's own file) become `import` refs pointing
14881
+ * at that file. Also applies to `node_modules`-published collections:
14882
+ * `dist/types/` mirrors `dist/collection/` 1:1, so the same math works after
14883
+ * swapping one for the other (type-only declarations don't survive
14884
+ * compilation to `.js`, so a reference has to point at the `.d.ts` tree).
14885
+ *
14886
+ * @param members inherited members whose type references should be re-anchored
14887
+ * @param extendedClassFileName absolute path of the file declaring the extended class
14888
+ * @param cmpSourceFilePath absolute path of the extending component's source file
14889
+ * @returns the same members, with their type references re-anchored
14890
+ */
14891
+ const reanchorInheritedTypeReferences = (members, extendedClassFileName, cmpSourceFilePath) => {
14892
+ const extendedClassDir = dirname$1(normalizePath(extendedClassFileName, false));
14893
+ const cmpDir = dirname$1(normalizePath(cmpSourceFilePath, false));
14894
+ if (extendedClassDir === cmpDir) return members;
14895
+ const isCollectionModule = isNodeModulePath(extendedClassFileName);
14896
+ const toDeclarationPath = (path) => isCollectionModule ? path.replace("/collection/", "/types/") : path;
14897
+ members.forEach((member) => {
14898
+ const references = member.complexType?.references;
14899
+ if (!references) return;
14900
+ Object.values(references).forEach((reference) => {
14901
+ if (reference.location === "import" && reference.path?.startsWith(".")) {
14902
+ const typeModulePath = toDeclarationPath(join$2(extendedClassDir, reference.path));
14903
+ reference.path = ensureRelativeSpecifier(relative$1(cmpDir, typeModulePath));
14904
+ } else if (reference.location === "local") {
14905
+ const extendedClassModule = toDeclarationPath(normalizePath(extendedClassFileName, false).replace(/\.(tsx|ts|js)$/, ""));
14906
+ reference.location = "import";
14907
+ reference.path = ensureRelativeSpecifier(relative$1(cmpDir, extendedClassModule));
14908
+ }
14909
+ });
14910
+ });
14911
+ return members;
14912
+ };
14913
+ //#endregion
14914
+ //#region src/compiler/transformers/static-to-meta/class-extension/compiler-ctx-merge.ts
14444
14915
  /**
14445
- * When a parent-class source file is fetched directly from disk (via
14446
- * {@link tsGetSourceFile}) rather than from the compiler's moduleMap cache, it
14447
- * arrives with its original decorator syntax intact. The static-meta parsers
14448
- * (`parseStaticProps`, `parseStaticStates`, etc.) only understand the static-
14449
- * getter form produced by {@link convertDecoratorsToStatic}.
14450
- *
14451
- * This helper creates a self-contained mini TypeScript program for the single
14452
- * file and runs the decorator→static transformer on it, returning the
14453
- * transformed source file. Prop types may be under-resolved (external imports
14454
- * are not available in the mini program) and will fall back to `any`, which is
14455
- * acceptable for the purpose of walking the inheritance chain.
14456
- *
14916
+ * Converts a disk-fetched parent source file (still decorator syntax) to
14917
+ * static-getter form via a throwaway single-file program - `parseStatic*`
14918
+ * only understands the static-getter form {@link convertDecoratorsToStatic}
14919
+ * produces. Cross-file imports can't resolve in this mini program, so prop
14920
+ * types may fall back to `any`, which is fine for just walking the chain.
14457
14921
  * @param sourceFile the raw (decorator-syntax) source file from disk
14458
14922
  * @param config the current Stencil validated config
14459
- * @param target the script target to use when converting decorators to static (if needed)
14923
+ * @param target the script target to convert decorators with
14460
14924
  * @returns the source file with decorators converted to static getters
14461
14925
  */
14462
14926
  function convertDiskSourceFileDecorators(sourceFile, config, target = ts.ScriptTarget.ESNext) {
@@ -14477,26 +14941,24 @@ function convertDiskSourceFileDecorators(sourceFile, config, target = ts.ScriptT
14477
14941
  return ts.createSourceFile(sourceFile.fileName, printed, target, true);
14478
14942
  }
14479
14943
  /**
14480
- * Helper function to resolve and process an extended class from a module.
14481
- * This handles:
14482
- * 1. Resolving the module path
14483
- * 2. Getting the source file
14484
- * 3. Finding the class declaration
14485
- * 4. Adding to dependent classes tree
14486
- *
14487
- * @param compilerCtx - the current compiler context
14488
- * @param buildCtx - the current build context
14489
- * @param classDeclaration - the current class being analyzed
14490
- * @param currentSource - the source file of the current class
14491
- * @param moduleSpecifier - the module path to resolve
14492
- * @param className - the name of the class to find in the resolved module
14493
- * @param dependentClasses - the array to add found classes to
14494
- * @param typeChecker - the TypeScript type checker
14495
- * @param ogModule - the original module file of the class declaration
14496
- * @param targetScriptTarget - the script target to use when converting decorators to static (if needed)
14497
- * @returns the found class declaration or undefined
14944
+ * Resolves an `extends` target through a module specifier: resolves the
14945
+ * module, finds the named class/mixin-factory export, and adds it (and its
14946
+ * own ancestors) to `dependentClasses`. Follows one level of re-export (barrel file) when the
14947
+ * declaration isn't found directly in the resolved module.
14948
+ * @param compilerCtx the current compiler context
14949
+ * @param buildCtx the current build context
14950
+ * @param classDeclaration the current class being analyzed
14951
+ * @param currentSource the source file of the current class
14952
+ * @param moduleSpecifier the module path to resolve
14953
+ * @param className the name of the class to find in the resolved module
14954
+ * @param dependentClasses the array to add found classes to
14955
+ * @param typeChecker the TypeScript type checker
14956
+ * @param ogModule the original module file of the class declaration
14957
+ * @param targetScriptTarget the script target to convert decorators with, if needed
14958
+ * @param barrelHopsRemaining re-export hops still allowed before giving up
14959
+ * @returns the found class declaration, or `undefined`
14498
14960
  */
14499
- function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, currentSource, moduleSpecifier, className, dependentClasses, typeChecker, ogModule, targetScriptTarget = ts.ScriptTarget.ESNext) {
14961
+ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, currentSource, moduleSpecifier, className, dependentClasses, typeChecker, ogModule, targetScriptTarget = ts.ScriptTarget.ESNext, barrelHopsRemaining = 1) {
14500
14962
  let keepLooking = true;
14501
14963
  const foundFile = tsResolveModuleName(buildCtx.config, compilerCtx, moduleSpecifier, currentSource.fileName);
14502
14964
  if (!foundFile?.resolvedModule || !className) return;
@@ -14505,7 +14967,7 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
14505
14967
  foundSource = tsGetSourceFile(buildCtx.config, foundFile);
14506
14968
  if (!foundSource) {
14507
14969
  const err = buildWarn(buildCtx.diagnostics);
14508
- err.messageText = `Unable to resolve import "${moduleSpecifier}" from "${currentSource.fileName}".
14970
+ err.messageText = `Unable to resolve import "${moduleSpecifier}" from "${currentSource.fileName}".
14509
14971
  This can happen when trying to resolve .js files and "allowJs" is not set to "true" in your tsconfig.json.`;
14510
14972
  if (!buildCtx.config._isTesting) augmentDiagnosticWithNode(err, classDeclaration);
14511
14973
  return;
@@ -14514,8 +14976,10 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
14514
14976
  }
14515
14977
  const matchedStatement = foundSource.statements.find(matchesNamedDeclaration(className));
14516
14978
  if (!matchedStatement) {
14979
+ const reExport = barrelHopsRemaining > 0 ? findReExport(foundSource, className) : void 0;
14980
+ if (reExport) return resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, foundSource, reExport.moduleSpecifier, reExport.localName, dependentClasses, typeChecker, ogModule, targetScriptTarget, barrelHopsRemaining - 1);
14517
14981
  const err = buildWarn(buildCtx.diagnostics);
14518
- err.messageText = `Unable to find "${className}" in the imported module "${moduleSpecifier}".
14982
+ err.messageText = `Unable to find "${className}" in the imported module "${moduleSpecifier}".
14519
14983
  Please import class / mixin-factory declarations directly and not via barrel files.`;
14520
14984
  if (!buildCtx.config._isTesting) augmentDiagnosticWithNode(err, classDeclaration);
14521
14985
  return;
@@ -14535,71 +14999,20 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
14535
14999
  }
14536
15000
  return foundClassDeclaration;
14537
15001
  }
14538
- /**
14539
- * A recursive function that walks the AST to find a class declaration.
14540
- * @param node the current AST node
14541
- * @param depth the current depth in the AST
14542
- * @param name optional name of the class to find
14543
- * @returns the found class declaration or undefined
14544
- */
14545
- function findClassWalk(node, name, depth = 0) {
14546
- if (!node) return void 0;
14547
- if (node && ts.isClassDeclaration(node)) {
14548
- if (!name || node.name?.text === name) return node;
14549
- } else if (node && ts.isVariableDeclaration(node) && (!name || name === (node.name?.text || node.name?.escapedText)) && node.initializer && ts.isArrowFunction(node.initializer)) {
14550
- let found;
14551
- ts.forEachChild(node.initializer.body, (child) => {
14552
- if (found) return;
14553
- if (ts.isClassDeclaration(child)) found = child;
14554
- });
14555
- return found;
14556
- }
14557
- let found;
14558
- ts.forEachChild(node, (child) => {
14559
- if (found) return;
14560
- const result = findClassWalk(child, name, depth + 1);
14561
- if (result) found = result;
14562
- });
14563
- return found;
14564
- }
14565
- /**
14566
- * A function that checks if a statement matches a named declaration.
14567
- * @param name the name to match
14568
- * @returns a function that checks if a statement is a named declaration
14569
- */
14570
- function matchesNamedDeclaration(name) {
14571
- return function(stmt) {
14572
- if (ts.isClassDeclaration(stmt) && stmt.name?.text === name) return true;
14573
- if (ts.isFunctionDeclaration(stmt) && stmt.name?.text === name) return true;
14574
- if (ts.isVariableStatement(stmt)) {
14575
- for (const decl of stmt.declarationList.declarations) if (ts.isIdentifier(decl.name) && decl.name.text === name) return true;
14576
- }
14577
- return false;
14578
- };
14579
- }
14580
- /**
14581
- * Helper function to convert a .d.ts declaration file path to its corresponding
14582
- * .js source file path and get the source file from the compiler context.
14583
- * This is needed because in external projects the extended class may only be found as a .d.ts declaration.
14584
- * *
14585
- * @param declarationSourceFile the path to the .d.ts declaration file
14586
- * @param compilerCtx the current compiler context
14587
- * @returns the corresponding .js source file
14588
- */
14589
15002
  function convertDtsToJs(declarationSourceFile, compilerCtx) {
14590
15003
  const jsPath = normalizePath(declarationSourceFile.replace(/\.d\.ts$/, ".js").replace("/types/", "/collection/"));
14591
15004
  return compilerCtx.moduleMap.get(jsPath)?.staticSourceFile;
14592
15005
  }
14593
15006
  /**
14594
- * A recursive function that builds a tree of classes that extend from each other.
14595
- *
15007
+ * Recursively walks a class's heritage clauses to build a flat list of every
15008
+ * class it extends from (and their own ancestors in turn).
14596
15009
  * @param compilerCtx the current compiler context
14597
15010
  * @param classDeclaration a class declaration to analyze
14598
- * @param dependentClasses a flat array tree of classes that extend from each other
15011
+ * @param dependentClasses the flat array to accumulate found classes into
14599
15012
  * @param typeChecker the TypeScript type checker
14600
15013
  * @param buildCtx the current build context
14601
15014
  * @param ogModule the original module file of the class declaration
14602
- * @returns a flat array of classes that extend from each other, including the current class
15015
+ * @returns `dependentClasses`, mutated in place
14603
15016
  */
14604
15017
  function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeChecker, buildCtx, ogModule) {
14605
15018
  const hasHeritageClauses = classDeclaration.heritageClauses;
@@ -14616,10 +15029,10 @@ function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeC
14616
15029
  });
14617
15030
  classIdentifiers.forEach((extendee) => {
14618
15031
  try {
14619
- const symbol = typeChecker?.getSymbolAtLocation(extendee);
14620
- const aliasedSymbol = symbol ? typeChecker.getAliasedSymbol(symbol) : void 0;
14621
- let source = aliasedSymbol?.declarations?.[0].getSourceFile();
14622
- let declarations = aliasedSymbol?.declarations;
15032
+ let symbol = typeChecker?.getSymbolAtLocation(extendee);
15033
+ if (symbol && symbol.flags & ts.SymbolFlags.Alias) symbol = typeChecker.getAliasedSymbol(symbol);
15034
+ let source = symbol?.declarations?.[0].getSourceFile();
15035
+ let declarations = symbol?.declarations;
14623
15036
  if (source.fileName.endsWith(".d.ts")) {
14624
15037
  source = convertDtsToJs(source.fileName, compilerCtx);
14625
15038
  declarations = [...source.statements];
@@ -14691,7 +15104,8 @@ function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeC
14691
15104
  if (statement.importClause?.namedBindings && ts.isNamedImports(statement.importClause?.namedBindings)) statement.importClause?.namedBindings.elements.forEach((element) => {
14692
15105
  if (element.name.getText() === extendee.getText()) {
14693
15106
  const className = element.propertyName?.getText() || element.name.getText();
14694
- resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, currentSource, statement.moduleSpecifier.getText().replaceAll(/['"]/g, ""), className, dependentClasses, typeChecker, ogModule, targetScriptTarget);
15107
+ const moduleSpecifier = statement.moduleSpecifier.getText().replaceAll(/['"]/g, "");
15108
+ resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, currentSource, moduleSpecifier, className, dependentClasses, typeChecker, ogModule, targetScriptTarget);
14695
15109
  }
14696
15110
  });
14697
15111
  });
@@ -14700,17 +15114,15 @@ function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeC
14700
15114
  return dependentClasses;
14701
15115
  }
14702
15116
  /**
14703
- * Given a class declaration, this function will analyze its heritage clauses
14704
- * to find any extended classes, and then parse the static members of those
14705
- * extended classes to merge them into the current class's metadata.
14706
- *
14707
- * @param compilerCtx - the current compiler context
14708
- * @param typeChecker - the TypeScript type checker
14709
- * @param buildCtx - the current build context
14710
- * @param cmpNode - the extending class declaration
14711
- * @param staticMembers - the static members of the extending class to merge with the extended class members
14712
- * @param moduleFile - the module file of the extending class
14713
- * @returns an object containing merged metadata from extended classes
15117
+ * Analyzes a class's heritage clauses to find any extended classes, then
15118
+ * merges their static members into the extending class's own metadata.
15119
+ * @param compilerCtx the current compiler context
15120
+ * @param typeChecker the TypeScript type checker
15121
+ * @param buildCtx the current build context
15122
+ * @param cmpNode the extending class declaration
15123
+ * @param staticMembers the static members of the extending class
15124
+ * @param moduleFile the module file of the extending class
15125
+ * @returns the merged metadata from `cmpNode` and every class it extends
14714
15126
  */
14715
15127
  function mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, staticMembers, moduleFile) {
14716
15128
  const tree = buildExtendsTree(compilerCtx, cmpNode, [], typeChecker, buildCtx, moduleFile);
@@ -14727,10 +15139,10 @@ function mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, sta
14727
15139
  let deserializers = parseStaticSerializers(staticMembers, "deserializers");
14728
15140
  tree.forEach((extendedClass) => {
14729
15141
  const extendedStaticMembers = extendedClass.classNode.members.filter(isStaticGetter);
14730
- const mixinProps = parseStaticProps(extendedStaticMembers) ?? [];
15142
+ const mixinProps = reanchorInheritedTypeReferences(parseStaticProps(extendedStaticMembers) ?? [], extendedClass.fileName, moduleFile.sourceFilePath);
14731
15143
  const mixinStates = parseStaticStates(extendedStaticMembers) ?? [];
14732
- const mixinMethods = parseStaticMethods(extendedStaticMembers) ?? [];
14733
- const mixinEvents = parseStaticEvents(extendedStaticMembers) ?? [];
15144
+ const mixinMethods = reanchorInheritedTypeReferences(parseStaticMethods(extendedStaticMembers) ?? [], extendedClass.fileName, moduleFile.sourceFilePath);
15145
+ const mixinEvents = reanchorInheritedTypeReferences(parseStaticEvents(extendedStaticMembers) ?? [], extendedClass.fileName, moduleFile.sourceFilePath);
14734
15146
  const isMixin = mixinProps.length > 0 || mixinStates.length > 0 || mixinMethods.length > 0 || mixinEvents.length > 0;
14735
15147
  const module = compilerCtx.moduleMap.get(extendedClass.fileName);
14736
15148
  if (module) {
@@ -14772,6 +15184,8 @@ function mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, sta
14772
15184
  deserializers
14773
15185
  };
14774
15186
  }
15187
+ //#endregion
15188
+ //#region src/compiler/transformers/static-to-meta/class-extension/extract-inherited-meta.ts
14775
15189
  const EMPTY_DOCS = {
14776
15190
  text: "",
14777
15191
  tags: []
@@ -14807,19 +15221,14 @@ function extractDecoratorOptions(node) {
14807
15221
  return result;
14808
15222
  }
14809
15223
  /**
14810
- * Extract Stencil member metadata from source text using parse-only TypeScript
14811
- * (no Program, no TypeChecker). Handles both decorator syntax (.tsx source files)
14812
- * and compiled static getter syntax (.js collection files).
14813
- *
14814
- * @param code source text to parse
14815
- * @param className name of the class to extract metadata from
14816
- * @param fileName virtual filename used to determine script kind
14817
- * @returns extracted metadata, or null if the named class is not found
15224
+ * Same as {@link extractInheritedMeta}, but takes an already-parsed class
15225
+ * declaration directly - used for ancestors reached via `findClassWalk`
15226
+ * (e.g. a mixin factory's nested class, or a same-file ancestor), where
15227
+ * there's no standalone source text to re-parse.
15228
+ * @param classDecl the class declaration to extract metadata from
15229
+ * @returns extracted metadata
14818
15230
  */
14819
- function extractInheritedMeta(code, className, fileName = "__stencil_parent__.tsx") {
14820
- const scriptKind = fileName.endsWith(".tsx") || fileName.endsWith(".ts") ? ts.ScriptKind.TSX : ts.ScriptKind.JS;
14821
- const classDecl = ts.createSourceFile(fileName, code, ts.ScriptTarget.ESNext, true, scriptKind).statements.filter(ts.isClassDeclaration).find((c) => c.name?.text === className);
14822
- if (!classDecl) return null;
15231
+ function extractInheritedMetaFromClass(classDecl) {
14823
15232
  const methodNames = classDecl.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean);
14824
15233
  const staticMembers = classDecl.members.filter(isStaticGetter);
14825
15234
  if (staticMembers.some((m) => ts.isGetAccessorDeclaration(m) && ts.isIdentifier(m.name) && [
@@ -14919,11 +15328,68 @@ function extractInheritedMeta(code, className, fileName = "__stencil_parent__.ts
14919
15328
  methodNames
14920
15329
  };
14921
15330
  }
14922
- function getExtendsClassName(node) {
15331
+ //#endregion
15332
+ //#region src/compiler/transformers/static-to-meta/class-extension/resolve-import-merge.ts
15333
+ /**
15334
+ * Same purpose as `convertDiskSourceFileDecorators` in compiler-ctx-merge.ts,
15335
+ * but serves the already-parsed in-memory source directly instead of
15336
+ * re-reading it from disk - the parent source here comes from a
15337
+ * caller-supplied `resolveImport` callback and isn't guaranteed to
15338
+ * correspond to a real file on disk.
15339
+ * @param sourceFile the raw (decorator-syntax) parent source file, already parsed
15340
+ * @param config the current Stencil validated config
15341
+ * @returns the source converted to static-getter form, or `null` if the mini-program transform fails
15342
+ */
15343
+ function convertInMemorySourceDecorators(sourceFile, config) {
15344
+ const compilerOptions = {
15345
+ ...config.tsCompilerOptions,
15346
+ experimentalDecorators: true,
15347
+ noLib: true,
15348
+ noResolve: true,
15349
+ isolatedModules: false,
15350
+ target: sourceFile.languageVersion
15351
+ };
15352
+ const compilerHost = {
15353
+ getSourceFile: (fileName) => fileName === sourceFile.fileName ? sourceFile : void 0,
15354
+ writeFile: () => {},
15355
+ getDefaultLibFileName: () => "lib.d.ts",
15356
+ useCaseSensitiveFileNames: () => false,
15357
+ getCanonicalFileName: (fileName) => fileName,
15358
+ getCurrentDirectory: () => "",
15359
+ getNewLine: () => "\n",
15360
+ fileExists: (fileName) => fileName === sourceFile.fileName,
15361
+ readFile: () => "",
15362
+ directoryExists: () => true,
15363
+ getDirectories: () => []
15364
+ };
15365
+ try {
15366
+ const program = ts.createProgram([sourceFile.fileName], compilerOptions, compilerHost);
15367
+ const typeChecker = program.getTypeChecker();
15368
+ const ownSourceFile = program.getSourceFile(sourceFile.fileName) ?? sourceFile;
15369
+ const result = ts.transform(ownSourceFile, [convertDecoratorsToStatic(config, [], typeChecker, program)]);
15370
+ const printed = ts.createPrinter({ removeComments: false }).printFile(result.transformed[0]);
15371
+ const scriptKind = sourceFile.fileName.endsWith(".tsx") || sourceFile.fileName.endsWith(".ts") ? ts.ScriptKind.TSX : ts.ScriptKind.JS;
15372
+ return ts.createSourceFile(sourceFile.fileName, printed, sourceFile.languageVersion, true, scriptKind);
15373
+ } catch {
15374
+ return null;
15375
+ }
15376
+ }
15377
+ /**
15378
+ * Reads the name(s) a class declaration extends from - either a single
15379
+ * identifier (`extends Foo`) or, for the mixin composition pattern, each
15380
+ * mixin factory argument (`extends Mixin(A, B)` > `['A', 'B']`).
15381
+ *
15382
+ * @param node the class declaration to inspect
15383
+ * @returns the extended identifier names, or an empty array if the class
15384
+ * doesn't extend anything recognizable
15385
+ */
15386
+ function getExtendsClassNames(node) {
14923
15387
  const heritage = node.heritageClauses?.find((h) => h.token === ts.SyntaxKind.ExtendsKeyword);
14924
- if (!heritage?.types.length) return null;
15388
+ if (!heritage?.types.length) return [];
14925
15389
  const expr = heritage.types[0].expression;
14926
- return ts.isIdentifier(expr) ? expr.text : null;
15390
+ if (ts.isIdentifier(expr)) return [expr.text];
15391
+ if (ts.isCallExpression(expr) && expr.expression.getText() === "Mixin") return expr.arguments.filter(ts.isIdentifier).map((id) => id.text);
15392
+ return [];
14927
15393
  }
14928
15394
  function findImportSpecifier(sf, localName) {
14929
15395
  for (const stmt of sf.statements) {
@@ -14939,17 +15405,208 @@ function findImportSpecifier(sf, localName) {
14939
15405
  return null;
14940
15406
  }
14941
15407
  /**
15408
+ * A single-file mini-program (see `convertInMemorySourceDecorators`) can
15409
+ * never load an imported module's own `SourceFile`, so a type that's
15410
+ * genuinely imported still ends up classified `location: 'global'`
15411
+ *
15412
+ * This reclassifies those cases using the same syntactic import lookup used
15413
+ * to walk the extends chain: if the type name matches something imported in
15414
+ * the file that declares it, it's an import, not a global, regardless of
15415
+ * whether the mini-program could load that file - downstream consumers
15416
+ * (e.g. `@stencil/unplugin`'s own type expansion) resolve `path` themselves.
15417
+ *
15418
+ * @param members inherited members whose type references should be reclassified
15419
+ * @param declaringSf the source file that declares these members
15420
+ * @param declaringPath the resolved absolute path of `declaringSf`
15421
+ * @param resolveImport callback used to resolve a canonical id for the reclassified reference
15422
+ * @returns the same members, with `global` references reclassified where possible
15423
+ */
15424
+ function reclassifyGlobalTypeReferences(members, declaringSf, declaringPath, resolveImport) {
15425
+ members.forEach((member) => {
15426
+ const references = member.complexType?.references;
15427
+ if (!references) return;
15428
+ Object.entries(references).forEach(([typeName, reference]) => {
15429
+ if (reference.location !== "global") return;
15430
+ const specifier = findImportSpecifier(declaringSf, typeName);
15431
+ if (!specifier) return;
15432
+ const resolved = resolveImport(specifier, declaringPath);
15433
+ reference.location = "import";
15434
+ reference.path = specifier;
15435
+ reference.id = `${resolved?.path ?? specifier}::${typeName}`;
15436
+ });
15437
+ });
15438
+ return members;
15439
+ }
15440
+ /**
15441
+ * Looks for `name` as a direct top-level declaration in `sf`; if not found, follows one level of
15442
+ * re-export (barrel file) via `resolveImport` - matching `compiler-ctx-merge.ts`'s equivalent
15443
+ * one-hop fallback (see `findReExport` in `shared.ts` for why it's capped at one hop).
15444
+ *
15445
+ * @param sf the source file to search
15446
+ * @param path the resolved absolute path of `sf`
15447
+ * @param name the declaration name to find
15448
+ * @param resolveImport callback used to follow a re-export's module specifier
15449
+ * @returns the matched statement and the source file/path it was actually found in (which may
15450
+ * differ from `sf`/`path` if resolved through a re-export), or `undefined`
15451
+ */
15452
+ function findDeclarationOrReExport(sf, path, name, resolveImport) {
15453
+ const direct = sf.statements.find(matchesNamedDeclaration(name));
15454
+ if (direct) return {
15455
+ statement: direct,
15456
+ sourceFile: sf,
15457
+ path
15458
+ };
15459
+ const reExport = findReExport(sf, name);
15460
+ if (!reExport) return void 0;
15461
+ const resolved = resolveImport(reExport.moduleSpecifier, path);
15462
+ if (!resolved) return void 0;
15463
+ const { code, path: resolvedPath } = resolved;
15464
+ const isTs = resolvedPath.endsWith(".tsx") || resolvedPath.endsWith(".ts");
15465
+ const reExportSf = ts.createSourceFile(resolvedPath, code, ts.ScriptTarget.ESNext, true, isTs ? ts.ScriptKind.TSX : ts.ScriptKind.JS);
15466
+ const statement = reExportSf.statements.find(matchesNamedDeclaration(reExport.localName));
15467
+ if (!statement) return void 0;
15468
+ return {
15469
+ statement,
15470
+ sourceFile: reExportSf,
15471
+ path: resolvedPath
15472
+ };
15473
+ }
15474
+ /**
15475
+ * Recursively resolves a class's `extends` heritage into a flat, deduplicated
15476
+ * list of ancestor classes, using `resolveImport` (and same-file lookups)
15477
+ * instead of a TypeChecker - the `resolveImport`-callback equivalent of
15478
+ * `compiler-ctx-merge.ts`'s `buildExtendsTree`. Handles both a plain
15479
+ * `extends Foo` and `extends Mixin(A, B, ...)`, resolving each mixin
15480
+ * argument independently.
15481
+ *
15482
+ * A found ancestor that's wrapped in a mixin factory function (rather than a
15483
+ * plain class) stops that branch's recursion - the factory's own `extends`
15484
+ * target is a dynamic parameter (e.g. `Base`), not a statically resolvable
15485
+ * name.
15486
+ * @param classNode the class declaration whose heritage should be walked
15487
+ * @param sf the source file containing `classNode` (for import/statement lookups)
15488
+ * @param path the resolved absolute path of `sf`
15489
+ * @param resolveImport callback that resolves an import specifier to source code
15490
+ * @param visited cycle guard, keyed by `resolvedPath::name`
15491
+ * @param ancestors the flat array to accumulate found ancestors into
15492
+ * @param rootClassDeclaration the top-level component class, used to anchor any "not found" warning
15493
+ * @param buildCtx used to surface a warning when an imported extends/mixin target can't be found -
15494
+ * omit to resolve silently (e.g. from tests that don't care about diagnostics)
15495
+ */
15496
+ function resolveAncestors(classNode, sf, path, resolveImport, visited, ancestors, rootClassDeclaration, buildCtx) {
15497
+ const parentNames = getExtendsClassNames(classNode);
15498
+ for (const parentName of parentNames) {
15499
+ let foundClass;
15500
+ let foundSf = sf;
15501
+ let foundPath = path;
15502
+ let keepLooking = true;
15503
+ const sameFileStatement = sf.statements.find(matchesNamedDeclaration(parentName));
15504
+ if (sameFileStatement) {
15505
+ if (ts.isClassDeclaration(sameFileStatement)) foundClass = sameFileStatement;
15506
+ else {
15507
+ foundClass = findClassWalk(sameFileStatement);
15508
+ keepLooking = false;
15509
+ }
15510
+ } else {
15511
+ const specifier = findImportSpecifier(sf, parentName);
15512
+ if (!specifier) continue;
15513
+ const resolved = resolveImport(specifier, path);
15514
+ if (!resolved) continue;
15515
+ const { code, path: resolvedPath } = resolved;
15516
+ const visitKey = `${resolvedPath}::${parentName}`;
15517
+ if (visited.has(visitKey)) continue;
15518
+ visited.add(visitKey);
15519
+ const isTs = resolvedPath.endsWith(".tsx") || resolvedPath.endsWith(".ts");
15520
+ const found = findDeclarationOrReExport(ts.createSourceFile(resolvedPath, code, ts.ScriptTarget.ESNext, true, isTs ? ts.ScriptKind.TSX : ts.ScriptKind.JS), resolvedPath, parentName, resolveImport);
15521
+ if (!found) {
15522
+ if (buildCtx) {
15523
+ const err = buildWarn(buildCtx.diagnostics);
15524
+ err.messageText = `Unable to find "${parentName}" in the imported module "${specifier}".
15525
+ Please import class / mixin-factory declarations directly and not via barrel files.`;
15526
+ if (!buildCtx.config._isTesting) augmentDiagnosticWithNode(err, rootClassDeclaration);
15527
+ }
15528
+ continue;
15529
+ }
15530
+ foundSf = found.sourceFile;
15531
+ foundPath = found.path;
15532
+ if (ts.isClassDeclaration(found.statement)) foundClass = found.statement;
15533
+ else {
15534
+ foundClass = findClassWalk(found.statement);
15535
+ keepLooking = false;
15536
+ }
15537
+ }
15538
+ if (!foundClass || ancestors.some((a) => a.classNode === foundClass)) continue;
15539
+ ancestors.push({
15540
+ classNode: foundClass,
15541
+ sourceFile: foundSf,
15542
+ path: foundPath
15543
+ });
15544
+ if (keepLooking) resolveAncestors(foundClass, foundSf, foundPath, resolveImport, visited, ancestors, rootClassDeclaration, buildCtx);
15545
+ }
15546
+ }
15547
+ /**
15548
+ * Extracts Stencil member metadata for a single resolved ancestor - static
15549
+ * getter form, or decorator syntax run through a throwaway single-file
15550
+ * program so real `complexType` info is computed, falling back to the
15551
+ * type-blind `extractInheritedMetaFromClass` walk if that program fails.
15552
+ * @param ancestor the resolved ancestor to extract metadata from
15553
+ * @param cmpSourceFile the extending component's source file (re-anchor target)
15554
+ * @param resolveImport callback that resolves an import specifier to source code
15555
+ * @param config used to compute real `complexType` info via a mini `ts.Program`
15556
+ * @returns the ancestor's metadata
15557
+ */
15558
+ function extractAncestorMeta(ancestor, cmpSourceFile, resolveImport, config) {
15559
+ const { classNode, sourceFile: parentSf, path: resolvedPath } = ancestor;
15560
+ const className = classNode.name?.text;
15561
+ const parentStaticMembers = classNode.members.filter(isStaticGetter);
15562
+ let resolvedClassNode = classNode;
15563
+ let resolvedStaticMembers = parentStaticMembers;
15564
+ let hasUsableStaticMembers = parentStaticMembers.some((m) => ts.isGetAccessorDeclaration(m) && ts.isIdentifier(m.name) && [
15565
+ "properties",
15566
+ "states",
15567
+ "events",
15568
+ "listeners",
15569
+ "watchers",
15570
+ "methods"
15571
+ ].includes(m.name.text));
15572
+ if (!hasUsableStaticMembers && className) {
15573
+ const converted = convertInMemorySourceDecorators(parentSf, config);
15574
+ const convertedClass = converted && findClassWalk(converted, className);
15575
+ if (convertedClass) {
15576
+ resolvedClassNode = convertedClass;
15577
+ resolvedStaticMembers = convertedClass.members.filter(isStaticGetter);
15578
+ hasUsableStaticMembers = true;
15579
+ }
15580
+ }
15581
+ if (!hasUsableStaticMembers) return extractInheritedMetaFromClass(classNode);
15582
+ return {
15583
+ properties: reanchorInheritedTypeReferences(reclassifyGlobalTypeReferences(parseStaticProps(resolvedStaticMembers) ?? [], parentSf, resolvedPath, resolveImport), resolvedPath, cmpSourceFile.fileName),
15584
+ states: parseStaticStates(resolvedStaticMembers) ?? [],
15585
+ methods: reanchorInheritedTypeReferences(reclassifyGlobalTypeReferences(parseStaticMethods(resolvedStaticMembers) ?? [], parentSf, resolvedPath, resolveImport), resolvedPath, cmpSourceFile.fileName),
15586
+ events: reanchorInheritedTypeReferences(reclassifyGlobalTypeReferences(parseStaticEvents(resolvedStaticMembers) ?? [], parentSf, resolvedPath, resolveImport), resolvedPath, cmpSourceFile.fileName),
15587
+ listeners: parseStaticListeners(resolvedStaticMembers) ?? [],
15588
+ watchers: parseStaticWatchers(resolvedStaticMembers) ?? [],
15589
+ methodNames: resolvedClassNode.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean)
15590
+ };
15591
+ }
15592
+ /**
14942
15593
  * Resolves the inheritance chain for a component using a caller-supplied
14943
- * `resolveImport` callback instead of the full compiler infrastructure.
14944
- * Safe to call from `transpileSync`/`transpileAsync` (no TypeChecker needed).
15594
+ * `resolveImport` callback instead of the full compiler infrastructure -
15595
+ * safe to call from `transpileSync`/`transpileAsync` (no TypeChecker needed).
15596
+ * Handles both a plain `extends Foo` and the mixin composition pattern
15597
+ * (`extends Mixin(A, B, ...)`).
14945
15598
  *
14946
15599
  * @param cmpNode the component's class declaration
14947
15600
  * @param staticMembers static getter members already parsed from the component
14948
15601
  * @param sourceFile the source file containing the component (for import resolution)
14949
15602
  * @param resolveImport callback that resolves an import specifier to source code
15603
+ * @param config used to compute real `complexType` info for decorator-syntax
15604
+ * parent classes via a mini `ts.Program`
15605
+ * @param buildCtx used to surface a warning when an imported extends/mixin target can't be
15606
+ * found - optional so existing (non-diagnostic-checking) callers aren't forced to supply one
14950
15607
  * @returns merged metadata including all inherited members
14951
15608
  */
14952
- function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceFile, resolveImport) {
15609
+ function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceFile, resolveImport, config, buildCtx) {
14953
15610
  let doesExtend = false;
14954
15611
  let properties = parseStaticProps(staticMembers);
14955
15612
  let states = parseStaticStates(staticMembers);
@@ -14960,42 +15617,10 @@ function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceF
14960
15617
  let classMethods = cmpNode.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean);
14961
15618
  const serializers = [];
14962
15619
  const deserializers = [];
14963
- let currentNode = cmpNode;
14964
- let currentSf = sourceFile;
14965
- let currentPath = sourceFile.fileName;
14966
- const visited = /* @__PURE__ */ new Set();
14967
- while (true) {
14968
- const parentClassName = getExtendsClassName(currentNode);
14969
- if (!parentClassName) break;
14970
- const specifier = findImportSpecifier(currentSf, parentClassName);
14971
- if (!specifier) break;
14972
- const resolved = resolveImport(specifier, currentPath);
14973
- if (!resolved) break;
14974
- const { code, path: resolvedPath } = resolved;
14975
- if (visited.has(resolvedPath)) break;
14976
- visited.add(resolvedPath);
14977
- const isTs = resolvedPath.endsWith(".tsx") || resolvedPath.endsWith(".ts");
14978
- const parentSf = ts.createSourceFile(resolvedPath, code, ts.ScriptTarget.ESNext, true, isTs ? ts.ScriptKind.TSX : ts.ScriptKind.JS);
14979
- const parentClass = parentSf.statements.filter(ts.isClassDeclaration).find((c) => c.name?.text === parentClassName);
14980
- if (!parentClass) break;
14981
- const parentStaticMembers = parentClass.members.filter(isStaticGetter);
14982
- const parentMeta = parentStaticMembers.some((m) => ts.isGetAccessorDeclaration(m) && ts.isIdentifier(m.name) && [
14983
- "properties",
14984
- "states",
14985
- "events",
14986
- "listeners",
14987
- "watchers",
14988
- "methods"
14989
- ].includes(m.name.text)) ? {
14990
- properties: parseStaticProps(parentStaticMembers),
14991
- states: parseStaticStates(parentStaticMembers),
14992
- methods: parseStaticMethods(parentStaticMembers),
14993
- events: parseStaticEvents(parentStaticMembers),
14994
- listeners: parseStaticListeners(parentStaticMembers),
14995
- watchers: parseStaticWatchers(parentStaticMembers),
14996
- methodNames: parentClass.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean)
14997
- } : extractInheritedMeta(code, parentClassName, resolvedPath);
14998
- if (!parentMeta) break;
15620
+ const ancestors = [];
15621
+ resolveAncestors(cmpNode, sourceFile, sourceFile.fileName, resolveImport, /* @__PURE__ */ new Set(), ancestors, cmpNode, buildCtx);
15622
+ ancestors.forEach((ancestor) => {
15623
+ const parentMeta = extractAncestorMeta(ancestor, sourceFile, resolveImport, config);
14999
15624
  doesExtend = true;
15000
15625
  const mixinPropsExcludingStates = parentMeta.properties.filter((mp) => !states.some((s) => s.name === mp.name));
15001
15626
  const mixinStatesExcludingProps = parentMeta.states.filter((ms) => !properties.some((p) => p.name === ms.name));
@@ -15006,10 +15631,7 @@ function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceF
15006
15631
  listeners = [...deDupeMembers(parentMeta.listeners, listeners), ...listeners];
15007
15632
  watchers = [...deDupeMembers(parentMeta.watchers, watchers), ...watchers];
15008
15633
  classMethods = [...classMethods, ...parentMeta.methodNames];
15009
- currentNode = parentClass;
15010
- currentSf = parentSf;
15011
- currentPath = resolvedPath;
15012
- }
15634
+ });
15013
15635
  return {
15014
15636
  doesExtend,
15015
15637
  properties,
@@ -15127,9 +15749,7 @@ const parseStaticPatches = (encapsulation, staticMembers) => {
15127
15749
  case "clone":
15128
15750
  result.clone = true;
15129
15751
  break;
15130
- case "insert":
15131
- result.insert = true;
15132
- break;
15752
+ case "insert": result.insert = true;
15133
15753
  }
15134
15754
  return Object.keys(result).length > 0 ? result : null;
15135
15755
  };
@@ -15293,8 +15913,9 @@ const parseStaticComponentMeta = (compilerCtx, typeChecker, cmpNode, moduleFile,
15293
15913
  const staticMembers = cmpNode.members.filter(isStaticGetter);
15294
15914
  const tagName = getComponentTagName(staticMembers);
15295
15915
  if (tagName == null) return cmpNode;
15296
- const { doesExtend, properties, states, methods, listeners, events, watchers, classMethods, serializers, deserializers } = transformOpts?.resolveImport ? mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, moduleFile.staticSourceFile, transformOpts.resolveImport) : mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, staticMembers, moduleFile);
15297
- const docs = serializeSymbol(typeChecker, typeChecker ? typeChecker.getSymbolAtLocation(cmpNode.name) : void 0);
15916
+ const { doesExtend, properties, states, methods, listeners, events, watchers, classMethods, serializers, deserializers } = transformOpts?.resolveImport ? mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, moduleFile.staticSourceFile, transformOpts.resolveImport, buildCtx.config, buildCtx) : mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, staticMembers, moduleFile);
15917
+ const symbol = typeChecker ? typeChecker.getSymbolAtLocation(cmpNode.name) : void 0;
15918
+ const docs = serializeSymbol(typeChecker, symbol);
15298
15919
  const isCollectionDependency = moduleFile.isCollectionDependency;
15299
15920
  const encapsulation = parseStaticEncapsulation(staticMembers);
15300
15921
  const cmp = {
@@ -15382,6 +16003,7 @@ const parseStaticComponentMeta = (compilerCtx, typeChecker, cmpNode, moduleFile,
15382
16003
  htmlAttrNames: [],
15383
16004
  htmlTagNames: [],
15384
16005
  htmlParts: [],
16006
+ htmlSlots: [],
15385
16007
  isUpdateable: false,
15386
16008
  potentialCmpRefs: [],
15387
16009
  dependents: [],
@@ -15404,9 +16026,11 @@ const parseStaticComponentMeta = (compilerCtx, typeChecker, cmpNode, moduleFile,
15404
16026
  cmp.hasModernPropertyDecls = detectModernPropDeclarations(cmpNode) || doesExtend;
15405
16027
  cmp.htmlAttrNames = unique(cmp.htmlAttrNames);
15406
16028
  cmp.htmlTagNames = unique(cmp.htmlTagNames);
16029
+ cmp.htmlSlots = unique(cmp.htmlSlots);
15407
16030
  cmp.hasSlot = cmp.hasSlot || cmp.htmlTagNames.includes("slot");
15408
16031
  cmp.potentialCmpRefs = unique(cmp.potentialCmpRefs);
15409
16032
  setComponentBuildConditionals(cmp);
16033
+ if (cmp.isPlain && cmpNode.heritageClauses?.some((c) => c.token === ts.SyntaxKind.ExtendsKeyword)) cmp.isPlain = false;
15410
16034
  if (transformOpts && transformOpts.componentMetadata === "compilerstatic") cmpNode = addComponentMetaStatic(cmpNode, cmp);
15411
16035
  const foundIndex = moduleFile.cmps.findIndex((c) => c.tagName === cmp.tagName && c.sourceFilePath === cmp.sourceFilePath);
15412
16036
  if (foundIndex > -1) moduleFile.cmps[foundIndex] = cmp;
@@ -15414,22 +16038,32 @@ const parseStaticComponentMeta = (compilerCtx, typeChecker, cmpNode, moduleFile,
15414
16038
  compilerCtx.nodeMap.set(cmpNode, cmp);
15415
16039
  return cmpNode;
15416
16040
  };
16041
+ /**
16042
+ * Check whether a class declaration is a Stencil component, i.e. it's
16043
+ * decorated with `@Component({ tag: ... })`.
16044
+ * @param classNode the class declaration to check
16045
+ * @returns whether `classNode` is a Stencil component class
16046
+ */
16047
+ const isStencilComponentClass = (classNode) => {
16048
+ const decorator = ts.getDecorators(classNode)?.[0];
16049
+ return decorator != null && ts.isCallExpression(decorator.expression) && decorator.expression.arguments.length === 1 && ts.isObjectLiteralExpression(decorator.expression.arguments[0]) && decorator.expression.arguments[0].properties.some((prop) => ts.isPropertyAssignment(prop) && prop.name.getText() === "tag");
16050
+ };
15417
16051
  const validateComponentMembers = (node, buildCtx) => {
15418
16052
  /**
15419
16053
  * validate if:
15420
16054
  */
15421
- if (ts.isGetAccessorDeclaration(node) && ts.isIdentifier(node.name) && typeof node.name.escapedText === "string" && BLACKLISTED_COMPONENT_METHODS.includes(node.name.escapedText) && node.parent && ts.isClassDeclaration(node.parent)) {
16055
+ if (ts.isGetAccessorDeclaration(node) && ts.isIdentifier(node.name) && typeof node.name.escapedText === "string" && BLACKLISTED_COMPONENT_METHODS.includes(node.name.escapedText) && node.parent && ts.isClassDeclaration(node.parent) && isStencilComponentClass(node.parent)) {
15422
16056
  const propName = node.name.escapedText;
15423
- const decorator = ts.getDecorators(node.parent)[0];
15424
- /**
15425
- * the class is actually a Stencil component, has a decorator with a property named "tag"
15426
- */
15427
- if (ts.isCallExpression(decorator.expression) && decorator.expression.arguments.length === 1 && ts.isObjectLiteralExpression(decorator.expression.arguments[0]) && decorator.expression.arguments[0].properties.some((prop) => ts.isPropertyAssignment(prop) && prop.name.getText() === "tag")) {
15428
- const componentName = node.parent.name.getText();
15429
- const err = buildWarn(buildCtx.diagnostics);
15430
- err.messageText = `The component "${componentName}" has a getter called "${propName}". This getter is reserved for use by Stencil components and should not be defined by the user.`;
15431
- augmentDiagnosticWithNode(err, node);
15432
- }
16057
+ const componentName = node.parent.name.getText();
16058
+ const err = buildWarn(buildCtx.diagnostics);
16059
+ err.messageText = `The component "${componentName}" has a getter called "${propName}". This getter is reserved for use by Stencil components and should not be defined by the user.`;
16060
+ augmentDiagnosticWithNode(err, node);
16061
+ }
16062
+ if (ts.isMethodDeclaration(node) && ts.isIdentifier(node.name) && node.name.escapedText === "componentShouldUpdate" && node.parameters.length > 1 && node.parent && ts.isClassDeclaration(node.parent) && isStencilComponentClass(node.parent)) {
16063
+ const componentName = node.parent.name.getText();
16064
+ const err = buildWarn(buildCtx.diagnostics);
16065
+ err.messageText = `The component "${componentName}" defines "componentShouldUpdate" with ${node.parameters.length} parameters. As of Stencil v5, "componentShouldUpdate" is called once per render with a single "changes" argument (a map of prop/state names to "{ newVal, oldVal }") instead of once per prop with "(newVal, oldVal, propName)". This method will still compile, but any extra parameters will be "undefined" at runtime.`;
16066
+ augmentDiagnosticWithNode(err, node);
15433
16067
  }
15434
16068
  };
15435
16069
  const parseVirtualProps = (docs) => {
@@ -15472,7 +16106,7 @@ const parseModuleImport = (config, compilerCtx, buildCtx, moduleFile, dirPath, i
15472
16106
  importPath = normalizePath(importPath);
15473
16107
  moduleFile.localImports.push(importPath);
15474
16108
  } else if (importPath.startsWith(".")) {
15475
- importPath = normalizePath(resolve$2(dirPath, importPath));
16109
+ importPath = normalizePath(join$2(dirPath, importPath));
15476
16110
  moduleFile.localImports.push(importPath);
15477
16111
  } else addExternalImport(config, compilerCtx, buildCtx, moduleFile, moduleFile.sourceFilePath, importPath, resolveCollections, !importNode.importClause);
15478
16112
  }
@@ -15538,7 +16172,8 @@ const updateModule = (config, compilerCtx, buildCtx, tsSourceFile, sourceFileTex
15538
16172
  const prevModuleFile = getModule(compilerCtx, sourceFilePath);
15539
16173
  if (prevModuleFile && prevModuleFile.staticSourceFileText === sourceFileText) return prevModuleFile;
15540
16174
  const srcDirPath = dirname$1(sourceFilePath);
15541
- emitFilePath = normalizePath(join$2(srcDirPath, basename$1(emitFilePath)));
16175
+ const emitFileName = basename$1(emitFilePath);
16176
+ emitFilePath = normalizePath(join$2(srcDirPath, emitFileName));
15542
16177
  const moduleFile = createModule(tsSourceFile, sourceFileText, emitFilePath);
15543
16178
  if (emitFilePath.endsWith(".js.map")) {
15544
16179
  moduleFile.sourceMapPath = emitFilePath;
@@ -15590,15 +16225,18 @@ const updateModule = (config, compilerCtx, buildCtx, tsSourceFile, sourceFileTex
15590
16225
  //#region src/compiler/transformers/collection/parse-collection-components.ts
15591
16226
  const parseCollectionComponents = (config, compilerCtx, buildCtx, collectionDir, collectionManifest, collection) => {
15592
16227
  if (collectionManifest.mixins) collectionManifest.mixins.forEach((mixinPath) => {
15593
- transpileCollectionModule(config, compilerCtx, buildCtx, collection, join$2(collectionDir, mixinPath));
16228
+ const fullPath = join$2(collectionDir, mixinPath);
16229
+ transpileCollectionModule(config, compilerCtx, buildCtx, collection, fullPath);
15594
16230
  });
15595
16231
  if (collectionManifest.entries) collectionManifest.entries.forEach((entryPath) => {
15596
- transpileCollectionModule(config, compilerCtx, buildCtx, collection, join$2(collectionDir, entryPath));
16232
+ const componentPath = join$2(collectionDir, entryPath);
16233
+ transpileCollectionModule(config, compilerCtx, buildCtx, collection, componentPath);
15597
16234
  });
15598
16235
  };
15599
16236
  const transpileCollectionModule = (config, compilerCtx, buildCtx, collection, inputFileName) => {
15600
16237
  const sourceText = compilerCtx.fs.readFileSync(inputFileName);
15601
- return updateModule(config, compilerCtx, buildCtx, ts.createSourceFile(inputFileName, sourceText, ts.ScriptTarget.ES2017, true, ts.ScriptKind.JS), sourceText, inputFileName, void 0, collection);
16238
+ const sourceFile = ts.createSourceFile(inputFileName, sourceText, ts.ScriptTarget.ES2017, true, ts.ScriptKind.JS);
16239
+ return updateModule(config, compilerCtx, buildCtx, sourceFile, sourceText, inputFileName, void 0, collection);
15602
16240
  };
15603
16241
  //#endregion
15604
16242
  //#region src/compiler/transformers/collection/parse-collection-manifest.ts
@@ -15628,7 +16266,8 @@ const parseCollectionDependencies = (collectionManifest) => {
15628
16266
  };
15629
16267
  const parseGlobal = (config, compilerCtx, buildCtx, collectionDir, collectionManifest, collection) => {
15630
16268
  if (typeof collectionManifest.global !== "string") return;
15631
- collection.global = transpileCollectionModule(config, compilerCtx, buildCtx, collection, normalizePath(join$2(collectionDir, collectionManifest.global)));
16269
+ const sourceFilePath = normalizePath(join$2(collectionDir, collectionManifest.global));
16270
+ collection.global = transpileCollectionModule(config, compilerCtx, buildCtx, collection, sourceFilePath);
15632
16271
  };
15633
16272
  const parseBundles = (collectionManifest) => {
15634
16273
  if (invalidArrayData(collectionManifest.bundles)) return [];
@@ -15646,12 +16285,14 @@ const parseCollection = (config, compilerCtx, buildCtx, moduleId, pkgJsonFilePat
15646
16285
  let collection = compilerCtx.collections.find((c) => c.collectionName === collectionName);
15647
16286
  if (collection != null) return collection;
15648
16287
  const collectionPackageRootDir = dirname$1(pkgJsonFilePath);
15649
- const collectionFilePath = join$2(collectionPackageRootDir, pkgData.collection ?? pkgData.collection);
16288
+ const collectionManifestPath = pkgData.collection ?? pkgData.collection;
16289
+ const collectionFilePath = join$2(collectionPackageRootDir, collectionManifestPath);
15650
16290
  const relPath = relative$1(config.rootDir, collectionFilePath);
15651
16291
  config.logger.debug(`load collection: ${collectionName}, ${relPath}`);
15652
16292
  const collectionJsonStr = compilerCtx.fs.readFileSync(collectionFilePath);
15653
16293
  if (!collectionJsonStr) return null;
15654
- collection = parseCollectionManifest(config, compilerCtx, buildCtx, collectionName, normalizePath(dirname$1(collectionFilePath)), collectionJsonStr);
16294
+ const collectionDir = normalizePath(dirname$1(collectionFilePath));
16295
+ collection = parseCollectionManifest(config, compilerCtx, buildCtx, collectionName, collectionDir, collectionJsonStr);
15655
16296
  collection.moduleId = moduleId;
15656
16297
  if (pkgData.module && pkgData.module !== pkgData.main) collection.hasExports = true;
15657
16298
  collection.moduleDir = collectionPackageRootDir;
@@ -15695,7 +16336,8 @@ const resolveAndIngestCollection = (config, compilerCtx, buildCtx, containingFil
15695
16336
  })) return;
15696
16337
  buildCtx.collections.push(collection);
15697
16338
  if (Array.isArray(collection.dependencies)) collection.dependencies.forEach((dependencyModuleId) => {
15698
- resolveAndIngestCollection(config, compilerCtx, buildCtx, dirname$1(pkgJsonFilePath), dependencyModuleId, resolveCollections);
16339
+ const resolveFromDir = dirname$1(pkgJsonFilePath);
16340
+ resolveAndIngestCollection(config, compilerCtx, buildCtx, resolveFromDir, dependencyModuleId, resolveCollections);
15699
16341
  });
15700
16342
  };
15701
16343
  /**
@@ -16116,7 +16758,8 @@ const runTsProgram = async (config, compilerCtx, buildCtx, tsBuilder) => {
16116
16758
  const changedmodules = Array.from(compilerCtx.changedModules.keys());
16117
16759
  buildCtx.debug("Transpiled modules: " + JSON.stringify(changedmodules, null, "\n"));
16118
16760
  buildCtx.moduleFiles = Array.from(compilerCtx.moduleMap.values());
16119
- const { components: filteredComponents, excludedComponents } = filterExcludedComponents(getComponentsFromModules(buildCtx.moduleFiles), config);
16761
+ const allComponents = getComponentsFromModules(buildCtx.moduleFiles);
16762
+ const { components: filteredComponents, excludedComponents } = filterExcludedComponents(allComponents, config);
16120
16763
  buildCtx.components = filteredComponents;
16121
16764
  if (excludedComponents.length > 0 && typesOutputTarget.length > 0) excludedComponents.forEach((cmp) => {
16122
16765
  const srcPath = normalizePath(cmp.sourceFilePath);
@@ -16271,7 +16914,10 @@ const getComponentsUpdated = (compilerCtx, buildCtx) => {
16271
16914
  const changedScriptFiles = [];
16272
16915
  const checkedFiles = /* @__PURE__ */ new Set();
16273
16916
  const allModuleFiles = buildCtx.moduleFiles.filter((m) => m.localImports && m.localImports.length > 0);
16274
- while (filesToLookForImporters.length > 0) addTsFileImporters(allModuleFiles, filesToLookForImporters, checkedFiles, changedScriptFiles, filesToLookForImporters.shift());
16917
+ while (filesToLookForImporters.length > 0) {
16918
+ const scriptFile = filesToLookForImporters.shift();
16919
+ addTsFileImporters(allModuleFiles, filesToLookForImporters, checkedFiles, changedScriptFiles, scriptFile);
16920
+ }
16275
16921
  const tags = changedScriptFiles.reduce((acc, changedTsFile) => {
16276
16922
  const moduleFile = compilerCtx.moduleMap.get(changedTsFile);
16277
16923
  if (moduleFile != null) moduleFile.cmps.forEach((cmp) => {
@@ -16456,43 +17102,47 @@ function generateBuildStats(config, buildCtx) {
16456
17102
  const buildResults = buildCtx.buildResults;
16457
17103
  try {
16458
17104
  if (buildResults.hasError) return err({ diagnostics: buildResults.diagnostics });
16459
- else return ok({
16460
- timestamp: buildResults.timestamp,
16461
- compiler: {
16462
- name: config.sys.name,
16463
- version: config.sys.version
16464
- },
16465
- app: {
16466
- namespace: config.namespace,
16467
- fsNamespace: config.fsNamespace,
16468
- components: Object.keys(buildResults.componentGraph ?? {}).length,
16469
- entries: Object.keys(buildResults.componentGraph ?? {}).length,
16470
- bundles: buildResults.outputs.reduce((total, en) => total + en.files.length, 0),
16471
- outputs: getAppOutputs(config, buildResults)
16472
- },
16473
- options: {
16474
- minifyJs: !!config.minifyJs,
16475
- minifyCss: !!config.minifyCss
16476
- },
16477
- formats: {
16478
- esmBrowser: sanitizeBundlesForStats(buildCtx.esmBrowserComponentBundle),
16479
- esm: sanitizeBundlesForStats(buildCtx.esmComponentBundle),
16480
- commonjs: sanitizeBundlesForStats(buildCtx.commonJsComponentBundle)
16481
- },
16482
- components: getComponentsFileMap(config, buildCtx),
16483
- entries: buildCtx.entryModules,
16484
- componentGraph: buildResults.componentGraph ?? {},
16485
- sourceGraph: getSourceGraph(config, buildCtx),
16486
- rolldownResults: buildCtx.rolldownResults ?? { modules: [] },
16487
- collections: getCollections(config, buildCtx)
16488
- });
17105
+ else {
17106
+ const stats = {
17107
+ timestamp: buildResults.timestamp,
17108
+ compiler: {
17109
+ name: config.sys.name,
17110
+ version: config.sys.version
17111
+ },
17112
+ app: {
17113
+ namespace: config.namespace,
17114
+ fsNamespace: config.fsNamespace,
17115
+ components: Object.keys(buildResults.componentGraph ?? {}).length,
17116
+ entries: Object.keys(buildResults.componentGraph ?? {}).length,
17117
+ bundles: buildResults.outputs.reduce((total, en) => total + en.files.length, 0),
17118
+ outputs: getAppOutputs(config, buildResults)
17119
+ },
17120
+ options: {
17121
+ minifyJs: !!config.minifyJs,
17122
+ minifyCss: !!config.minifyCss
17123
+ },
17124
+ formats: {
17125
+ esmBrowser: sanitizeBundlesForStats(buildCtx.esmBrowserComponentBundle),
17126
+ esm: sanitizeBundlesForStats(buildCtx.esmComponentBundle),
17127
+ commonjs: sanitizeBundlesForStats(buildCtx.commonJsComponentBundle)
17128
+ },
17129
+ components: getComponentsFileMap(config, buildCtx),
17130
+ entries: buildCtx.entryModules,
17131
+ componentGraph: buildResults.componentGraph ?? {},
17132
+ sourceGraph: getSourceGraph(config, buildCtx),
17133
+ rolldownResults: buildCtx.rolldownResults ?? { modules: [] },
17134
+ collections: getCollections(config, buildCtx)
17135
+ };
17136
+ return ok(stats);
17137
+ }
16489
17138
  } catch (e) {
16490
- return err({ diagnostics: [{
17139
+ const diagnostic = {
16491
17140
  level: `error`,
16492
17141
  lines: [],
16493
17142
  messageText: `Generate Build Stats Error: ` + e,
16494
17143
  type: `build`
16495
- }] });
17144
+ };
17145
+ return err({ diagnostics: [diagnostic] });
16496
17146
  }
16497
17147
  }
16498
17148
  /**
@@ -16668,10 +17318,13 @@ const buildDone = async (config, compilerCtx, buildCtx, aborted) => {
16668
17318
  */
16669
17319
  const logHmr = (logger, hmr) => {
16670
17320
  if (hmr.componentsUpdated) cleanupUpdateMsg(logger, `updated component`, hmr.componentsUpdated);
16671
- if (hmr.inlineStylesUpdated) cleanupUpdateMsg(logger, `updated style`, hmr.inlineStylesUpdated.map((s) => s.styleTag).reduce((arr, v) => {
16672
- if (!arr.includes(v)) arr.push(v);
16673
- return arr;
16674
- }, []));
17321
+ if (hmr.inlineStylesUpdated) {
17322
+ const inlineStyles = hmr.inlineStylesUpdated.map((s) => s.styleTag).reduce((arr, v) => {
17323
+ if (!arr.includes(v)) arr.push(v);
17324
+ return arr;
17325
+ }, []);
17326
+ cleanupUpdateMsg(logger, `updated style`, inlineStyles);
17327
+ }
16675
17328
  if (hmr.externalStylesUpdated) cleanupUpdateMsg(logger, `updated stylesheet`, hmr.externalStylesUpdated);
16676
17329
  if (hmr.imagesUpdated) cleanupUpdateMsg(logger, `updated image`, hmr.imagesUpdated);
16677
17330
  };
@@ -16768,7 +17421,7 @@ const getPackageJsonRecommendations = (config, compilerCtx) => {
16768
17421
  * @returns an empty Promise
16769
17422
  */
16770
17423
  const validateBuildPackageJson = async (config, compilerCtx, buildCtx) => {
16771
- if (config.watch || buildCtx.packageJson == null) return;
17424
+ if (config.watch || config.devMode || buildCtx.packageJson == null) return;
16772
17425
  validatePackageJson(config, compilerCtx, buildCtx);
16773
17426
  const stencilCollectionOutputTargets = config.outputTargets.filter(isOutputTargetCollection);
16774
17427
  await Promise.all(stencilCollectionOutputTargets.map((stencilCollectionOT) => validateCollectionFields(config, compilerCtx, buildCtx, stencilCollectionOT)));
@@ -16908,26 +17561,30 @@ const validateCollectionFields = async (config, compilerCtx, buildCtx, outputTar
16908
17561
  * @param outputTarget the collection output target to validate against
16909
17562
  */
16910
17563
  const validatePackageFiles = async (config, compilerCtx, buildCtx, outputTarget) => {
16911
- if (!config.devMode && Array.isArray(buildCtx.packageJson.files)) {
16912
- const actualDistDir = normalizePath(relative$1(config.rootDir, outputTarget.dir));
16913
- if (!buildCtx.packageJson.files.some((userPath) => {
16914
- const normalizedUserPath = normalizePath(userPath).replace(/\/$/, "").replace(/^\.\//, "");
16915
- const normalizedDistDir = actualDistDir.replace(/\/$/, "").replace(/^\.\//, "");
16916
- if (normalizedUserPath === normalizedDistDir) return true;
16917
- const userPathWithSlash = normalizedUserPath + "/";
16918
- if (normalizedDistDir.startsWith(userPathWithSlash)) return true;
16919
- return false;
16920
- })) {
16921
- packageJsonWarn(config, compilerCtx, buildCtx, `package.json "files" array must contain the distribution directory "${actualDistDir}/" when generating a distribution.`, `"files"`);
16922
- return;
16923
- }
16924
- await Promise.all(buildCtx.packageJson.files.map(async (pkgFile) => {
16925
- if (!isGlob(pkgFile)) {
16926
- const absPath = join$2(dirname$1(config.packageJsonFilePath), pkgFile);
16927
- if (!await compilerCtx.fs.access(absPath)) packageJsonError(config, compilerCtx, buildCtx, `Unable to find "${pkgFile}" within the package.json "files" array.`, `"${pkgFile}"`);
16928
- }
16929
- }));
17564
+ if (!Array.isArray(buildCtx.packageJson.files)) return;
17565
+ const actualDistDir = normalizePath(relative$1(config.rootDir, outputTarget.dir));
17566
+ if (!buildCtx.packageJson.files.some((userPath) => {
17567
+ const normalizedUserPath = normalizePath(userPath).replace(/\/$/, "").replace(/^\.\//, "");
17568
+ const normalizedDistDir = actualDistDir.replace(/\/$/, "").replace(/^\.\//, "");
17569
+ if (normalizedUserPath === normalizedDistDir) return true;
17570
+ const userPathWithSlash = normalizedUserPath + "/";
17571
+ if (normalizedDistDir.startsWith(userPathWithSlash)) return true;
17572
+ return false;
17573
+ })) {
17574
+ const msg = `package.json "files" array must contain the distribution directory "${actualDistDir}/" when generating a distribution.`;
17575
+ packageJsonWarn(config, compilerCtx, buildCtx, msg, `"files"`);
17576
+ return;
16930
17577
  }
17578
+ await Promise.all(buildCtx.packageJson.files.map(async (pkgFile) => {
17579
+ if (!isGlob(pkgFile)) {
17580
+ const packageJsonDir = dirname$1(config.packageJsonFilePath);
17581
+ const absPath = join$2(packageJsonDir, pkgFile);
17582
+ if (!await compilerCtx.fs.access(absPath)) {
17583
+ const msg = `Unable to find "${pkgFile}" within the package.json "files" array.`;
17584
+ packageJsonError(config, compilerCtx, buildCtx, msg, `"${pkgFile}"`);
17585
+ }
17586
+ }
17587
+ }));
16931
17588
  };
16932
17589
  /**
16933
17590
  * Check that the `collection` field is set correctly in `package.json` for the
@@ -16940,7 +17597,10 @@ const validatePackageFiles = async (config, compilerCtx, buildCtx, outputTarget)
16940
17597
  const validateCollectionField = (config, compilerCtx, buildCtx, outputTarget) => {
16941
17598
  if (outputTarget.dir) {
16942
17599
  const collectionRel = normalizePath(join$2(relative$1(config.rootDir, outputTarget.dir), COLLECTION_MANIFEST_FILE_NAME), false);
16943
- if (!buildCtx.packageJson.collection || normalizePath(buildCtx.packageJson.collection, false) !== collectionRel) packageJsonWarn(config, compilerCtx, buildCtx, `package.json "collection" property should be set to ${collectionRel} when generating a distribution bundle.`, `"collection"`);
17600
+ if (!buildCtx.packageJson.collection || normalizePath(buildCtx.packageJson.collection, false) !== collectionRel) {
17601
+ const msg = `package.json "collection" property should be set to ${collectionRel} when generating a distribution bundle.`;
17602
+ packageJsonWarn(config, compilerCtx, buildCtx, msg, `"collection"`);
17603
+ }
16944
17604
  }
16945
17605
  };
16946
17606
  /**
@@ -16984,7 +17644,8 @@ const validateManifestJson = (config, compilerCtx, buildCtx) => {
16984
17644
  try {
16985
17645
  const manifestContent = await compilerCtx.fs.readFile(manifestFilePath);
16986
17646
  if (manifestContent) try {
16987
- await validateManifestJsonData(compilerCtx, buildCtx, manifestFilePath, JSON.parse(manifestContent));
17647
+ const manifestData = JSON.parse(manifestContent);
17648
+ await validateManifestJsonData(compilerCtx, buildCtx, manifestFilePath, manifestData);
16988
17649
  } catch (e) {
16989
17650
  const err = buildError(buildCtx.diagnostics);
16990
17651
  err.header = `Invalid manifest.json: ${e}`;
@@ -17005,7 +17666,8 @@ const validateManifestJsonIcon = async (compilerCtx, buildCtx, manifestFilePath,
17005
17666
  return;
17006
17667
  }
17007
17668
  if (iconSrc.startsWith("/")) iconSrc = iconSrc.slice(1);
17008
- const iconPath = join$2(dirname$1(manifestFilePath), iconSrc);
17669
+ const manifestDir = dirname$1(manifestFilePath);
17670
+ const iconPath = join$2(manifestDir, iconSrc);
17009
17671
  if (!await compilerCtx.fs.access(iconPath)) {
17010
17672
  const msg = `Unable to find manifest icon "${manifestIcon.src}"`;
17011
17673
  buildJsonFileError(compilerCtx, buildCtx.diagnostics, manifestFilePath, msg, `"${manifestIcon.src}"`);
@@ -17067,11 +17729,18 @@ const generateRootExport = (config, buildCtx, loaderBundle, standalone, types) =
17067
17729
  if (!(currentImport && isValidRootExport(config, currentImport, loaderBundle, standalone))) {
17068
17730
  const primaryDir = loaderBundle?.dir ?? standalone?.dir;
17069
17731
  if (primaryDir) {
17070
- execSync(`npm pkg set "exports[.][import]"="${normalizePath(relative$1(config.rootDir, join$2(primaryDir, "index.js")))}"`);
17071
- if (loaderBundle?.cjs) execSync(`npm pkg set "exports[.][require]"="${normalizePath(relative$1(config.rootDir, join$2(loaderBundle.dir, "index.cjs")))}"`);
17732
+ const importPath = normalizePath(relative$1(config.rootDir, join$2(primaryDir, "index.js")));
17733
+ execSync(`npm pkg set "exports[.][import]"="${importPath}"`);
17734
+ if (loaderBundle?.cjs) {
17735
+ const requirePath = normalizePath(relative$1(config.rootDir, join$2(loaderBundle.dir, "index.cjs")));
17736
+ execSync(`npm pkg set "exports[.][require]"="${requirePath}"`);
17737
+ }
17072
17738
  }
17073
17739
  }
17074
- if (types?.dir) execSync(`npm pkg set "exports[.][types]"="${normalizePath(relative$1(config.rootDir, join$2(types.dir, "index.d.ts")))}"`);
17740
+ if (types?.dir) {
17741
+ const typesPath = normalizePath(relative$1(config.rootDir, join$2(types.dir, "index.d.ts")));
17742
+ execSync(`npm pkg set "exports[.][types]"="${typesPath}"`);
17743
+ }
17075
17744
  };
17076
17745
  /**
17077
17746
  * Check if the current root export import path is valid
@@ -17116,12 +17785,17 @@ const ensureRelativePrefix = (path) => {
17116
17785
  */
17117
17786
  const generateLoaderExport = (config, loaderBundle, types) => {
17118
17787
  const esmDir = join$2(loaderBundle.dir, "esm");
17119
- execSync(`npm pkg set "exports[./loader][import]"="${ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(esmDir, "loader.js"))))}"`);
17788
+ const esmLoaderPath = ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(esmDir, "loader.js"))));
17789
+ execSync(`npm pkg set "exports[./loader][import]"="${esmLoaderPath}"`);
17120
17790
  if (loaderBundle.cjs) {
17121
17791
  const cjsDir = join$2(loaderBundle.dir, "cjs");
17122
- execSync(`npm pkg set "exports[./loader][require]"="${ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(cjsDir, "loader.cjs"))))}"`);
17792
+ const cjsLoaderPath = ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(cjsDir, "loader.cjs"))));
17793
+ execSync(`npm pkg set "exports[./loader][require]"="${cjsLoaderPath}"`);
17794
+ }
17795
+ if (types?.dir) {
17796
+ const typesPath = ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(types.dir, "loader.d.ts"))));
17797
+ execSync(`npm pkg set "exports[./loader][types]"="${typesPath}"`);
17123
17798
  }
17124
- if (types?.dir) execSync(`npm pkg set "exports[./loader][types]"="${ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(types.dir, "loader.d.ts"))))}"`);
17125
17799
  };
17126
17800
  /**
17127
17801
  * Generate per-component exports for standalone output.
@@ -17315,8 +17989,10 @@ const compilerRequest = async (config, compilerCtx, data) => {
17315
17989
  return results;
17316
17990
  }
17317
17991
  } catch (e) {
17318
- if (e) if (e instanceof Error && e.stack) results.content = `/*\n${e.stack}\n*/`;
17319
- else results.content = `/*\n${e}\n*/`;
17992
+ if (e) {
17993
+ if (e instanceof Error && e.stack) results.content = `/*\n${e.stack}\n*/`;
17994
+ else results.content = `/*\n${e}\n*/`;
17995
+ }
17320
17996
  results.status = 500;
17321
17997
  }
17322
17998
  return results;
@@ -17733,7 +18409,8 @@ const createWatchBuild = async (config, compilerCtx) => {
17733
18409
  filesAdded.forEach((f) => currentlyBuildingFiles.add(f));
17734
18410
  filesUpdated.forEach((f) => currentlyBuildingFiles.add(f));
17735
18411
  filesDeleted.forEach((f) => currentlyBuildingFiles.add(f));
17736
- await onBuild(incrementalCompiler.rebuild());
18412
+ const tsBuilder = incrementalCompiler.rebuild();
18413
+ await onBuild(tsBuilder);
17737
18414
  } finally {
17738
18415
  currentlyBuildingFiles.clear();
17739
18416
  isBuilding = false;
@@ -17773,7 +18450,7 @@ const createWatchBuild = async (config, compilerCtx) => {
17773
18450
  if (!compilerCtx.fs.accessSync(key)) compilerCtx.moduleMap.delete(key);
17774
18451
  }
17775
18452
  });
17776
- new Set([...filesUpdated, ...filesAdded]).forEach((filePath) => {
18453
+ (/* @__PURE__ */ new Set([...filesUpdated, ...filesAdded])).forEach((filePath) => {
17777
18454
  compilerCtx.addWatchFile(filePath);
17778
18455
  });
17779
18456
  dirsAdded.clear();
@@ -17786,7 +18463,8 @@ const createWatchBuild = async (config, compilerCtx) => {
17786
18463
  const result = await build(config, compilerCtx, buildCtx, tsBuilder);
17787
18464
  if (result === null) {
17788
18465
  incrementalCompiler.refreshRootNames();
17789
- await onBuild(incrementalCompiler.rebuild());
18466
+ const freshTsBuilder = incrementalCompiler.rebuild();
18467
+ await onBuild(freshTsBuilder);
17790
18468
  return;
17791
18469
  }
17792
18470
  if (!result.hasError) isRebuild = true;
@@ -17814,7 +18492,8 @@ const createWatchBuild = async (config, compilerCtx) => {
17814
18492
  ...(config.watchExternalDirs || []).map((dir) => watchFiles(compilerCtx, dir))
17815
18493
  ]);
17816
18494
  incrementalCompiler = new IncrementalCompiler(config);
17817
- await onBuild(incrementalCompiler.rebuild());
18495
+ const tsBuilder = incrementalCompiler.rebuild();
18496
+ await onBuild(tsBuilder);
17818
18497
  return watchWaiter;
17819
18498
  };
17820
18499
  /**
@@ -17857,9 +18536,7 @@ const createWatchBuild = async (config, compilerCtx) => {
17857
18536
  case "fileUpdate":
17858
18537
  filesUpdated.add(filePath);
17859
18538
  break;
17860
- case "fileDelete":
17861
- filesDeleted.add(filePath);
17862
- break;
18539
+ case "fileDelete": filesDeleted.add(filePath);
17863
18540
  }
17864
18541
  if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) tsFilesToInvalidate.add(filePath);
17865
18542
  config.logger.debug(`WATCH_BUILD::fs_event_change - type=${eventKind}, path=${filePath}, time=${(/* @__PURE__ */ new Date()).getTime()}`);
@@ -18124,7 +18801,7 @@ var Cache = class {
18124
18801
  }
18125
18802
  };
18126
18803
  const MAX_FAILED = 100;
18127
- const ONE_DAY = 1e3 * 60 * 60 * 24;
18804
+ const ONE_DAY = 864e5;
18128
18805
  const ONE_WEEK = ONE_DAY * 7;
18129
18806
  const EXP_STORAGE_KEY = `last_clear_expired_cache`;
18130
18807
  const CACHE_DIR_README = `# Stencil Cache Directory
@@ -18283,6 +18960,9 @@ const validateDocs$1 = (config, diagnostics, userOutputs) => {
18283
18960
  userOutputs.filter(isOutputTargetDocsCustomElementsManifest).forEach((cemOutput) => {
18284
18961
  docsOutputs.push(validateCustomElementsManifestOutputTarget(config, cemOutput));
18285
18962
  });
18963
+ userOutputs.filter(isOutputTargetDocsAgentSkill).forEach((agentSkillOutput) => {
18964
+ docsOutputs.push(validateAgentSkillOutputTarget(config, agentSkillOutput));
18965
+ });
18286
18966
  return docsOutputs;
18287
18967
  };
18288
18968
  const validateReadmeOutputTarget = (config, outputTarget) => {
@@ -18322,6 +19002,13 @@ const validateVScodeDocsOutputTarget = (config, diagnostics, outputTarget) => {
18322
19002
  if (!isBoolean$1(outputTarget.skipInDev)) outputTarget.skipInDev = !config._docsFlag;
18323
19003
  return outputTarget;
18324
19004
  };
19005
+ const DEFAULT_AGENT_SKILL_DIR = "dist/skill";
19006
+ const validateAgentSkillOutputTarget = (config, outputTarget) => {
19007
+ outputTarget.dir = getAbsolutePath(config, outputTarget.dir || DEFAULT_AGENT_SKILL_DIR);
19008
+ outputTarget.name = toSkillName(outputTarget.name || config.fsNamespace);
19009
+ if (!isBoolean$1(outputTarget.skipInDev)) outputTarget.skipInDev = !config._docsFlag;
19010
+ return outputTarget;
19011
+ };
18325
19012
  const validateCustomElementsManifestOutputTarget = (config, outputTarget) => {
18326
19013
  if (!isString$1(outputTarget.file)) outputTarget.file = "custom-elements.json";
18327
19014
  if (!isAbsolute$1(outputTarget.file)) outputTarget.file = join$2(config.rootDir, outputTarget.file);
@@ -18350,9 +19037,10 @@ const validateGlobalStyle = (config, userOutputs) => {
18350
19037
  const input = isString$1(outputTarget.input) ? getAbsolutePath(config, outputTarget.input) : config.globalStyle ?? void 0;
18351
19038
  let fileName;
18352
19039
  if (isString$1(outputTarget.fileName)) fileName = outputTarget.fileName;
18353
- else if (input) if (isString$1(outputTarget.input)) fileName = basename(input);
18354
- else fileName = `${config.fsNamespace}.css`;
18355
- else fileName = `${config.fsNamespace}.css`;
19040
+ else if (input) {
19041
+ if (isString$1(outputTarget.input)) fileName = basename(input);
19042
+ else fileName = `${config.fsNamespace}.css`;
19043
+ } else fileName = `${config.fsNamespace}.css`;
18356
19044
  const validInjectValues = [
18357
19045
  "none",
18358
19046
  "client",
@@ -18375,9 +19063,10 @@ const validateGlobalStyle = (config, userOutputs) => {
18375
19063
  //#region src/compiler/config/outputs/validate-lazy.ts
18376
19064
  const validateLazy = (config, userOutputs) => {
18377
19065
  return userOutputs.filter(isOutputTargetDistLazy).map((o) => {
19066
+ const dir = getAbsolutePath(config, o.dir || join$2("dist", config.fsNamespace));
18378
19067
  return {
18379
19068
  type: DIST_LAZY,
18380
- esmDir: getAbsolutePath(config, o.dir || join$2("dist", config.fsNamespace)),
19069
+ esmDir: dir,
18381
19070
  isBrowserBuild: true,
18382
19071
  empty: isBoolean$1(o.empty) ? o.empty : true
18383
19072
  };
@@ -18441,7 +19130,8 @@ const validateLoaderBundle = (config, diagnostics, userOutputs) => {
18441
19130
  if (!config.devMode || !loaderBundleOutput.skipInDev) {
18442
19131
  const esmDir = join$2(loaderBundleOutput.dir, "esm");
18443
19132
  const cjsDir = loaderBundleOutput.cjs ? join$2(loaderBundleOutput.dir, "cjs") : void 0;
18444
- const typesDir = getAbsolutePath(config, userOutputs.find(isOutputTargetTypes)?.dir ?? "dist/types");
19133
+ const typesOutput = userOutputs.find(isOutputTargetTypes);
19134
+ const typesDir = getAbsolutePath(config, typesOutput?.dir ?? "dist/types");
18445
19135
  outputs.push({
18446
19136
  type: DIST_LAZY,
18447
19137
  esmDir,
@@ -19253,6 +19943,8 @@ const validateConfig = (userConfig = {}, bootstrapConfig) => {
19253
19943
  const ldp = validatedConfig.compat.lightDomPatches;
19254
19944
  if (ldp === void 0) validatedConfig.compat.lightDomPatches = true;
19255
19945
  else if (typeof ldp !== "boolean" && typeof ldp !== "object") validatedConfig.compat.lightDomPatches = true;
19946
+ validatedConfig.compat.suppressPublicNameWarnings = !!validatedConfig.compat.suppressPublicNameWarnings;
19947
+ validatedConfig.compat.suppressEventNameWarnings = !!validatedConfig.compat.suppressEventNameWarnings;
19256
19948
  setBooleanConfig(validatedConfig, "watch", false);
19257
19949
  setBooleanConfig(validatedConfig, "profile", validatedConfig.devMode);
19258
19950
  setBooleanConfig(validatedConfig, "writeLog", false);
@@ -19260,8 +19952,6 @@ const validateConfig = (userConfig = {}, bootstrapConfig) => {
19260
19952
  setBooleanConfig(validatedConfig, "autoprefixCss", false);
19261
19953
  setBooleanConfig(validatedConfig, "validateTypes", !validatedConfig._isTesting);
19262
19954
  setBooleanConfig(validatedConfig, "allowInlineScripts", true);
19263
- setBooleanConfig(validatedConfig, "suppressReservedPublicNameWarnings", false);
19264
- setBooleanConfig(validatedConfig, "suppressReservedEventNameWarnings", false);
19265
19955
  if (!isString$1(validatedConfig.taskQueue)) validatedConfig.taskQueue = "async";
19266
19956
  if (!validatedConfig.env) validatedConfig.env = {};
19267
19957
  validateOutputTargets(validatedConfig, diagnostics);
@@ -19271,6 +19961,7 @@ const validateConfig = (userConfig = {}, bootstrapConfig) => {
19271
19961
  else validatedConfig.bundles = [];
19272
19962
  if (!Array.isArray(validatedConfig.excludeComponents)) validatedConfig.excludeComponents = [];
19273
19963
  if (!Array.isArray(validatedConfig.collections)) validatedConfig.collections = [];
19964
+ if (!Array.isArray(validatedConfig.modes)) validatedConfig.modes = [];
19274
19965
  validateWorkers(validatedConfig);
19275
19966
  setBooleanConfig(validatedConfig, "devInspector", validatedConfig.devMode);
19276
19967
  setBooleanConfig(validatedConfig, "enableCache", true);
@@ -20213,7 +20904,8 @@ const autoprefixCss = async (cssText, opts, filePath, minify = false) => {
20213
20904
  diagnostics: []
20214
20905
  };
20215
20906
  try {
20216
- const targets = getTargets(opts != null && typeof opts === "object" && Array.isArray(opts.targets) ? opts.targets : DEFAULT_BROWSER_TARGETS);
20907
+ const browserTargets = opts != null && typeof opts === "object" && Array.isArray(opts.targets) ? opts.targets : DEFAULT_BROWSER_TARGETS;
20908
+ const targets = getTargets(browserTargets);
20217
20909
  output.output = transform({
20218
20910
  filename: filePath ?? "style.css",
20219
20911
  code: Buffer.from(cssText),
@@ -20497,7 +21189,8 @@ const parseCss = (css, filePath) => {
20497
21189
  };
20498
21190
  const atquery = (name) => {
20499
21191
  const pos = position();
20500
- const m = match(new RegExp("^@" + name + " *([^{]+)"));
21192
+ const regex = new RegExp("^@" + name + " *([^{]+)");
21193
+ const m = match(regex);
20501
21194
  if (!m) return null;
20502
21195
  const media = trim(m[1]);
20503
21196
  if (!open()) return error(`@${name} missing '{'`);
@@ -20516,7 +21209,8 @@ const parseCss = (css, filePath) => {
20516
21209
  */
20517
21210
  const nestedAtQuery = (name) => {
20518
21211
  const pos = position();
20519
- const m = match(new RegExp("^@" + name + " *([^{]+)"));
21212
+ const regex = new RegExp("^@" + name + " *([^{]+)");
21213
+ const m = match(regex);
20520
21214
  if (!m) return null;
20521
21215
  const media = trim(m[1]);
20522
21216
  const decls = declarations();
@@ -20774,8 +21468,10 @@ const serializeCssVisitNode = (opts, node, index, len) => {
20774
21468
  const nodeType = node.type;
20775
21469
  if (nodeType === 4) return serializeCssDeclaration(node, index, len);
20776
21470
  if (nodeType === 14) return serializeCssRule(opts, node);
20777
- if (nodeType === 1) if (node.comment?.[0] === "!") return `/*${node.comment}*/`;
20778
- else return "";
21471
+ if (nodeType === 1) {
21472
+ if (node.comment?.[0] === "!") return `/*${node.comment}*/`;
21473
+ else return "";
21474
+ }
20779
21475
  if (nodeType === 10) return serializeCssMedia(opts, node);
20780
21476
  if (nodeType === 11) return serializeCssContainer(opts, node);
20781
21477
  if (nodeType === 8) return serializeCssKeyframes(opts, node);
@@ -21007,7 +21703,8 @@ const crawlAnchorsForNextUrls = (prerenderConfig, diagnostics, baseUrl, currentU
21007
21703
  return standardFilterAnchor(diagnostics, anchor, currentUrl);
21008
21704
  }).map((anchor) => {
21009
21705
  if (typeof prerenderConfig.normalizeUrl === "function") try {
21010
- return standardNormalizeUrl(diagnostics, prerenderConfig.normalizeUrl(anchor.href, currentUrl).href, currentUrl);
21706
+ const userNormalizedUrl = prerenderConfig.normalizeUrl(anchor.href, currentUrl);
21707
+ return standardNormalizeUrl(diagnostics, userNormalizedUrl.href, currentUrl);
21011
21708
  } catch (e) {
21012
21709
  catchError(diagnostics, e);
21013
21710
  }
@@ -21109,7 +21806,7 @@ const extname$1 = (str) => {
21109
21806
  const parts = str.split(".");
21110
21807
  return parts[parts.length - 1].toLowerCase();
21111
21808
  };
21112
- const SKIP_EXT = new Set([
21809
+ const SKIP_EXT = /* @__PURE__ */ new Set([
21113
21810
  "zip",
21114
21811
  "rar",
21115
21812
  "tar",
@@ -21153,8 +21850,10 @@ const getPrerenderConfig = async (diagnostics, prerenderConfigPath) => {
21153
21850
  const results = await nodeRequire(prerenderConfigPath);
21154
21851
  diagnostics.push(...results.diagnostics);
21155
21852
  const mod = results.module?.default ?? results.module;
21156
- if (mod != null && typeof mod === "object") if (mod.config != null && typeof mod.config === "object") Object.assign(prerenderConfig, mod.config);
21157
- else Object.assign(prerenderConfig, mod);
21853
+ if (mod != null && typeof mod === "object") {
21854
+ if (mod.config != null && typeof mod.config === "object") Object.assign(prerenderConfig, mod.config);
21855
+ else Object.assign(prerenderConfig, mod);
21856
+ }
21158
21857
  }
21159
21858
  return prerenderConfig;
21160
21859
  };
@@ -21211,7 +21910,8 @@ const optimizeJs = async (inputOpts) => {
21211
21910
  sourceMap: null
21212
21911
  };
21213
21912
  try {
21214
- const minifyOpts = getTerserOptions({}, "latest", !!inputOpts.pretty);
21913
+ const prettyOutput = !!inputOpts.pretty;
21914
+ const minifyOpts = getTerserOptions({}, "latest", prettyOutput);
21215
21915
  const minifyResults = await minifyJs(inputOpts.input, minifyOpts);
21216
21916
  if (minifyResults.diagnostics.length > 0) result.diagnostics.push(...minifyResults.diagnostics);
21217
21917
  else {
@@ -21317,7 +22017,9 @@ s&&((s['data-opts']=s['data-opts']||{}).exclude=__EXCLUDE__);
21317
22017
  const addModulePreloads = (doc, hydrateOpts, hydrateResults, componentGraph) => {
21318
22018
  if (!componentGraph) return false;
21319
22019
  const staticComponents = hydrateOpts.staticComponents || [];
21320
- injectModulePreloads(doc, unique(flatOne(hydrateResults.components.filter((cmp) => !staticComponents.includes(cmp.tag)).map((cmp) => getScopeId(cmp.tag, cmp.mode)).map((scopeId) => componentGraph.get(scopeId) || []))));
22020
+ const cmpTags = hydrateResults.components.filter((cmp) => !staticComponents.includes(cmp.tag));
22021
+ const modulePreloads = unique(flatOne(cmpTags.map((cmp) => getScopeId(cmp.tag, cmp.mode)).map((scopeId) => componentGraph.get(scopeId) || [])));
22022
+ injectModulePreloads(doc, modulePreloads);
21321
22023
  return true;
21322
22024
  };
21323
22025
  const removeModulePreloads = (doc) => {
@@ -21426,14 +22128,16 @@ const hashPageStateAstAssets = async (sys, hydrateOpts, appDir, currentUrl, page
21426
22128
  };
21427
22129
  const getAttrUrls = (attrName, attrValue) => {
21428
22130
  const srcValues = [];
21429
- if (isString$1(attrValue)) if (attrName.toLowerCase() === "srcset") attrValue.split(",").map((a) => a.trim()).filter((a) => a.length > 0).forEach((src) => {
21430
- const spaceSplt = src.split(" ");
21431
- if (spaceSplt[0].length > 0) srcValues.push({
21432
- src: spaceSplt[0],
21433
- descriptor: spaceSplt[1]
22131
+ if (isString$1(attrValue)) {
22132
+ if (attrName.toLowerCase() === "srcset") attrValue.split(",").map((a) => a.trim()).filter((a) => a.length > 0).forEach((src) => {
22133
+ const spaceSplt = src.split(" ");
22134
+ if (spaceSplt[0].length > 0) srcValues.push({
22135
+ src: spaceSplt[0],
22136
+ descriptor: spaceSplt[1]
22137
+ });
21434
22138
  });
21435
- });
21436
- else srcValues.push({ src: attrValue });
22139
+ else srcValues.push({ src: attrValue });
22140
+ }
21437
22141
  return srcValues;
21438
22142
  };
21439
22143
  const setAttrUrls = (url, descriptor) => {
@@ -21558,10 +22262,12 @@ const prerenderWorker = async (sys, prerenderRequest) => {
21558
22262
  [s.id]: JSON.parse(s.content),
21559
22263
  components: hydrateResults.components.map((c) => c.tag)
21560
22264
  };
21561
- const dataFilePath = join$2(pageDir, `${s.id}.json`);
22265
+ const dataFileName = `${s.id}.json`;
22266
+ const dataFilePath = join$2(pageDir, dataFileName);
21562
22267
  await sys.writeFile(dataFilePath, JSON.stringify(data));
21563
22268
  } else {
21564
- const contentFilePath = join$2(pageDir, `${s.id}.txt`);
22269
+ const contentFileName = `${s.id}.txt`;
22270
+ const contentFilePath = join$2(pageDir, contentFileName);
21565
22271
  await sys.writeFile(contentFilePath, s.content);
21566
22272
  }
21567
22273
  }));
@@ -21669,7 +22375,8 @@ const transformCssToEsm = async (input) => {
21669
22375
  * @returns transformed ESM output
21670
22376
  */
21671
22377
  const transformCssToEsmSync = (input) => {
21672
- return generateTransformCssToEsm(input, transformCssToEsmModule(input));
22378
+ const results = transformCssToEsmModule(input);
22379
+ return generateTransformCssToEsm(input, results);
21673
22380
  };
21674
22381
  /**
21675
22382
  * Performs the actual transformation from CSS to ESM
@@ -21689,7 +22396,7 @@ const transformCssToEsmModule = (input) => {
21689
22396
  };
21690
22397
  if (input.docs) parseStyleDocs(results.styleDocs, input.input, input.mode);
21691
22398
  try {
21692
- const varNames = new Set([results.defaultVarName]);
22399
+ const varNames = /* @__PURE__ */ new Set([results.defaultVarName]);
21693
22400
  if (isString$1(input.tag) && input.encapsulation === "scoped") {
21694
22401
  const scopeId = getScopeId(input.tag, input.mode);
21695
22402
  results.styleText = scopeCss(results.styleText, scopeId, false);
@@ -21724,7 +22431,7 @@ const transformCssToEsmModule = (input) => {
21724
22431
  */
21725
22432
  const generateTransformCssToEsm = (input, results) => {
21726
22433
  const s = new MagicString("");
21727
- results.styleText = results.styleText.replace(/\n/g, " ").replace(/\r/g, " ").replace(/\t/g, " ").replace(/`/g, "\\`").replace(/\u000c/g, "\\f").replace(/\u0008/g, "\\b").replace(/\u000b/g, "\\v").replace(/\0/g, "\\0").replace(/\\/g, "\\\\");
22434
+ results.styleText = results.styleText.replace(/\\/g, "\\\\").replace(/\n/g, " ").replace(/\r/g, " ").replace(/\t/g, " ").replace(/\u000c/g, "\\\\f").replace(/\u0008/g, "\\\\b").replace(/\u000b/g, "\\\\v").replace(/\0/g, "\\\\0").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
21728
22435
  if (input.addTagTransformers) results.styleText = addTagTransformToCssString(results.styleText, input.tags);
21729
22436
  results.styleText = stripCssComments(results.styleText);
21730
22437
  if (input.module === "cjs") {
@@ -22009,9 +22716,10 @@ const getTsConfigPath = async (config, sys) => {
22009
22716
  path: "",
22010
22717
  content: ""
22011
22718
  };
22012
- if (isString$1(config.tsconfig)) if (!isAbsolute$1(config.tsconfig)) tsconfig.path = join$2(config.rootDir, config.tsconfig);
22013
- else tsconfig.path = config.tsconfig;
22014
- else tsconfig.path = join$2(config.rootDir, "tsconfig.json");
22719
+ if (isString$1(config.tsconfig)) {
22720
+ if (!isAbsolute$1(config.tsconfig)) tsconfig.path = join$2(config.rootDir, config.tsconfig);
22721
+ else tsconfig.path = config.tsconfig;
22722
+ } else tsconfig.path = join$2(config.rootDir, "tsconfig.json");
22015
22723
  tsconfig.content = await sys.readFile(tsconfig.path);
22016
22724
  if (!isString$1(tsconfig.content)) {
22017
22725
  tsconfig.path = join$2(config.rootDir, "tsconfig.json");
@@ -22256,13 +22964,15 @@ const addUrlToPendingQueue = (manager, queueUrl, fromUrl) => {
22256
22964
  };
22257
22965
  const drainPrerenderQueue = (results, manager) => {
22258
22966
  const nextUrl = manager.urlsPending.values().next();
22259
- if (!nextUrl.done) if (manager.urlsProcessing.size > manager.maxConcurrency) setTimeout(() => drainPrerenderQueue(results, manager));
22260
- else {
22261
- const url = nextUrl.value;
22262
- manager.urlsPending.delete(url);
22263
- manager.urlsProcessing.add(url);
22264
- prerenderUrl(results, manager, url);
22265
- if (manager.urlsProcessing.size < manager.maxConcurrency) manager.config.sys.nextTick(() => drainPrerenderQueue(results, manager));
22967
+ if (!nextUrl.done) {
22968
+ if (manager.urlsProcessing.size > manager.maxConcurrency) setTimeout(() => drainPrerenderQueue(results, manager));
22969
+ else {
22970
+ const url = nextUrl.value;
22971
+ manager.urlsPending.delete(url);
22972
+ manager.urlsProcessing.add(url);
22973
+ prerenderUrl(results, manager, url);
22974
+ if (manager.urlsProcessing.size < manager.maxConcurrency) manager.config.sys.nextTick(() => drainPrerenderQueue(results, manager));
22975
+ }
22266
22976
  }
22267
22977
  if (manager.urlsProcessing.size === 0 && manager.urlsPending.size === 0) {
22268
22978
  if (isFunction(manager.resolve)) {
@@ -22562,7 +23272,8 @@ const runPrerenderOutputTarget = async (workerCtx, results, diagnostics, config,
22562
23272
  if (debugDiagnostics.length > 0) config.logger.printDiagnostics(debugDiagnostics);
22563
23273
  }
22564
23274
  const duration = timeSpan.duration();
22565
- await generateRobotsTxt(manager, await generateSitemapXml(manager));
23275
+ const sitemapResults = await generateSitemapXml(manager);
23276
+ await generateRobotsTxt(manager, sitemapResults);
22566
23277
  const prerenderBuildErrors = prerenderDiagnostics.filter((d) => d.level === "error");
22567
23278
  const prerenderRuntimeErrors = prerenderDiagnostics.filter((d) => d.type === "runtime");
22568
23279
  if (prerenderBuildErrors.length > 0) {
@@ -22773,7 +23484,8 @@ const createSystem = (c) => {
22773
23484
  const itemStat = statSync(oldPath);
22774
23485
  if (!itemStat.error && !results.error) {
22775
23486
  if (itemStat.isFile) {
22776
- const createDirResults = createDirSync(dirname$1(newPath), { recursive: true });
23487
+ const newFileParentDir = dirname$1(newPath);
23488
+ const createDirResults = createDirSync(newFileParentDir, { recursive: true });
22777
23489
  const fileContent = items.get(oldPath).data;
22778
23490
  const writeResults = writeFileSync(newPath, fileContent);
22779
23491
  results.newDirs.push(...createDirResults.newDirs);
@@ -22795,7 +23507,10 @@ const createSystem = (c) => {
22795
23507
  isDirectory: true,
22796
23508
  isFile: false
22797
23509
  });
22798
- for (const oldDirItemChildPath of oldDirItemChildPaths) renameNewRecursiveSync(oldDirItemChildPath, oldDirItemChildPath.replace(oldPath, newPath), results);
23510
+ for (const oldDirItemChildPath of oldDirItemChildPaths) {
23511
+ const newDirItemChildPath = oldDirItemChildPath.replace(oldPath, newPath);
23512
+ renameNewRecursiveSync(oldDirItemChildPath, newDirItemChildPath, results);
23513
+ }
22799
23514
  }
22800
23515
  }
22801
23516
  };
@@ -23185,13 +23900,13 @@ const getTranspileConfigOpt = (value, validValues, defaultValue) => {
23185
23900
  if (validValues.has(value)) return value;
23186
23901
  return defaultValue;
23187
23902
  };
23188
- const VALID_EXPORT = new Set(["customelement", "module"]);
23189
- const VALID_METADATA = new Set(["compilerstatic", null]);
23190
- const VALID_MODULE = new Set(["cjs", "esm"]);
23191
- const VALID_PROXY = new Set(["defineproperty", null]);
23192
- const VALID_STYLE = new Set(["static"]);
23193
- const VALID_STYLE_IMPORT_DATA = new Set(["queryparams"]);
23194
- const VALID_TARGET = new Set([
23903
+ const VALID_EXPORT = /* @__PURE__ */ new Set(["customelement", "module"]);
23904
+ const VALID_METADATA = /* @__PURE__ */ new Set(["compilerstatic", null]);
23905
+ const VALID_MODULE = /* @__PURE__ */ new Set(["cjs", "esm"]);
23906
+ const VALID_PROXY = /* @__PURE__ */ new Set(["defineproperty", null]);
23907
+ const VALID_STYLE = /* @__PURE__ */ new Set(["static"]);
23908
+ const VALID_STYLE_IMPORT_DATA = /* @__PURE__ */ new Set(["queryparams"]);
23909
+ const VALID_TARGET = /* @__PURE__ */ new Set([
23195
23910
  "latest",
23196
23911
  "esnext",
23197
23912
  "es2020",
@@ -23351,8 +24066,10 @@ const transpile = async (code, opts = {}) => {
23351
24066
  patchTypescript(validatedConfig, null);
23352
24067
  transpileCode(validatedConfig, compileOpts, transformOpts, results);
23353
24068
  } else if (results.inputFileExtension === "d.ts") results.code = "";
23354
- else if (results.inputFileExtension === "css") await transpileCss(getTranspileCssConfig(opts, importData, results), results);
23355
- else if (results.inputFileExtension === "json") transpileJson(results);
24069
+ else if (results.inputFileExtension === "css") {
24070
+ const transformInput = getTranspileCssConfig(opts, importData, results);
24071
+ await transpileCss(transformInput, results);
24072
+ } else if (results.inputFileExtension === "json") transpileJson(results);
23356
24073
  } catch (e) {
23357
24074
  catchError(results.diagnostics, e);
23358
24075
  }
@@ -23376,8 +24093,10 @@ const transpileSync = (code, opts = {}) => {
23376
24093
  patchTypescript(validatedConfig, null);
23377
24094
  transpileCode(validatedConfig, compileOpts, transformOpts, results);
23378
24095
  } else if (results.inputFileExtension === "d.ts") results.code = "";
23379
- else if (results.inputFileExtension === "css") transpileCssSync(getTranspileCssConfig(opts, importData, results), results);
23380
- else if (results.inputFileExtension === "json") transpileJson(results);
24096
+ else if (results.inputFileExtension === "css") {
24097
+ const transformInput = getTranspileCssConfig(opts, importData, results);
24098
+ transpileCssSync(transformInput, results);
24099
+ } else if (results.inputFileExtension === "json") transpileJson(results);
23381
24100
  } catch (e) {
23382
24101
  catchError(results.diagnostics, e);
23383
24102
  }