@stencil/core 5.0.0-alpha.27 → 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-D43Ied7R.mjs → compiler-BbS9TDF_.mjs} +1845 -1118
  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-DKVq_Ud0.mjs → node-BQR4L-TG.mjs} +60 -58
  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 +74 -56
  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-ByxKj8bC.mjs +0 -1458
  44. /package/{LICENSE.md → LICENSE} +0 -0
@@ -1,14 +1,15 @@
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-ByxKj8bC.mjs";
5
- import { i as CustomElementsExportBehaviorOptions, o as buildEvents, r as createNodeLogger, t as createNodeSys } from "./node-DKVq_Ud0.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";
9
10
  import { fileURLToPath } from "node:url";
10
11
  import picomatch from "picomatch";
11
- import path$1, { basename as basename$1, dirname as dirname$1, extname, isAbsolute as isAbsolute$1, join as join$1 } from "path";
12
+ import path, { basename as basename$1, dirname as dirname$1, extname, isAbsolute as isAbsolute$1, join as join$1 } from "path";
12
13
  import { cloneDocument, createDocument, serializeNodeToHtml } from "@stencil/mock-doc";
13
14
  import postcss from "postcss";
14
15
  import postcssSafeParser from "postcss-safe-parser";
@@ -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.27";
32
- const buildId = "1783983631";
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: [],
@@ -256,7 +261,7 @@ const resetModuleLegacy = (moduleFile) => {
256
261
  */
257
262
  const getTsOptionsToExtend = (config) => {
258
263
  const cacheDir = config.cacheDir || config.sys.tmpDirSync();
259
- return {
264
+ const tsOptions = {
260
265
  experimentalDecorators: true,
261
266
  declaration: config.outputTargets.some(isOutputTargetTypes),
262
267
  module: config.tsCompilerOptions?.module || ts.ModuleKind.ESNext,
@@ -269,6 +274,8 @@ const getTsOptionsToExtend = (config) => {
269
274
  incremental: config.enableCache !== false,
270
275
  tsBuildInfoFile: config.enableCache !== false ? join$2(cacheDir, ".tsbuildinfo") : void 0
271
276
  };
277
+ if (config.tsCompilerOptions?.skipLibCheck === void 0) tsOptions.skipLibCheck = true;
278
+ return tsOptions;
272
279
  };
273
280
  //#endregion
274
281
  //#region src/compiler/transpile/create-build-program.ts
@@ -489,7 +496,7 @@ const getModuleImports = (moduleMap, filePath, importedModules) => {
489
496
  * build - everything else is a component-derived flag that the consumer recomputes itself
490
497
  * by scanning all components (including those from the collection).
491
498
  */
492
- const COLLECTION_CONFIG_FLAGS = new Set([
499
+ const COLLECTION_CONFIG_FLAGS = /* @__PURE__ */ new Set([
493
500
  "lightDomPatches",
494
501
  "slotChildNodes",
495
502
  "slotCloneNode",
@@ -753,11 +760,12 @@ function hostRefElementInternalsPropAccess() {
753
760
  */
754
761
  const updateLazyComponentConstructor = (classMembers, classNode, moduleFile, cmp) => {
755
762
  const cstrMethodArgs = [ts.factory.createParameterDeclaration(void 0, void 0, ts.factory.createIdentifier(HOST_REF_ARG))];
756
- updateConstructor(classNode, classMembers, [
763
+ const cstrStatements = [
757
764
  registerInstanceStatement(moduleFile),
758
765
  ...addCreateEvents(moduleFile, cmp),
759
766
  ...createLazyAttachInternalsBinding(cmp)
760
- ], cstrMethodArgs);
767
+ ];
768
+ updateConstructor(classNode, classMembers, cstrStatements, cstrMethodArgs);
761
769
  };
762
770
  /**
763
771
  * Create a statement containing an expression calling the `registerInstance`
@@ -951,19 +959,7 @@ function findTypeWithName(module, typeName) {
951
959
  function getOriginalTypeName(identifier, checker) {
952
960
  const possiblyAliasedSymbol = checker.getSymbolAtLocation(identifier);
953
961
  if (!possiblyAliasedSymbol) return;
954
- return unalias(possiblyAliasedSymbol, checker).getName();
955
- }
956
- /**
957
- * Check if a symbol is an alias of another symbol and, if so, use the
958
- * {@link ts.TypeChecker} to resolve the original. If not, just return the same
959
- * symbol.
960
- *
961
- * @param symbol the symbol of interest
962
- * @param checker a {@link ts.TypeChecker}
963
- * @returns a de-aliased symbol
964
- */
965
- function unalias(symbol, checker) {
966
- return symbol.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
962
+ return resolveAliasedSymbol(checker, possiblyAliasedSymbol).getName();
967
963
  }
968
964
  /**
969
965
  * Check that a {@link ts.Node} is a type-declaration-like node. For our
@@ -1264,38 +1260,41 @@ const objectLiteralToObjectMap = (objectLiteral, typeChecker, diagnostics, error
1264
1260
  const propName = getTextOfPropertyName(propAssignment.name);
1265
1261
  let val;
1266
1262
  if (ts.isShorthandPropertyAssignment(propAssignment)) val = getIdentifierValue(propName);
1267
- 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);
1268
- else val = propAssignment.initializer;
1269
- else switch (propAssignment.initializer.kind) {
1270
- case ts.SyntaxKind.ArrayLiteralExpression:
1271
- val = arrayLiteralToArray(propAssignment.initializer);
1272
- break;
1273
- case ts.SyntaxKind.ObjectLiteralExpression:
1274
- val = objectLiteralToObjectMap(propAssignment.initializer, typeChecker, diagnostics, errorNode);
1275
- break;
1276
- case ts.SyntaxKind.StringLiteral:
1277
- val = propAssignment.initializer.text;
1278
- break;
1279
- case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
1280
- val = propAssignment.initializer.text;
1281
- break;
1282
- case ts.SyntaxKind.TrueKeyword:
1283
- val = true;
1284
- break;
1285
- case ts.SyntaxKind.FalseKeyword:
1286
- val = false;
1287
- break;
1288
- case ts.SyntaxKind.Identifier:
1289
- const escapedText = propAssignment.initializer.escapedText;
1290
- if (escapedText === "String") val = String;
1291
- else if (escapedText === "Number") val = Number;
1292
- else if (escapedText === "Boolean") val = Boolean;
1293
- else if (escapedText === "undefined") val = void 0;
1294
- else if (escapedText === "null") val = null;
1295
- else val = getIdentifierValue(propAssignment.initializer.escapedText);
1296
- break;
1297
- case ts.SyntaxKind.PropertyAccessExpression:
1298
- 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
+ }
1299
1298
  }
1300
1299
  final[propName] = val;
1301
1300
  }
@@ -1313,7 +1312,8 @@ const objectLiteralToObjectMap = (objectLiteral, typeChecker, diagnostics, error
1313
1312
  */
1314
1313
  const resolveVarInObjectLiteral = (node, typeChecker, _diagnostics, _errorNode) => {
1315
1314
  if (ts.isIdentifier(node)) {
1316
- const symbol = typeChecker.getSymbolAtLocation(node);
1315
+ let symbol = typeChecker.getSymbolAtLocation(node);
1316
+ if (symbol && symbol.flags & ts.SymbolFlags.Alias) symbol = typeChecker.getAliasedSymbol(symbol);
1317
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.`);
1318
1318
  const declaration = symbol.valueDeclaration;
1319
1319
  if (ts.isVariableDeclaration(declaration)) {
@@ -1403,6 +1403,14 @@ const getEntityName = (entity) => {
1403
1403
  else return getEntityName(entity.left);
1404
1404
  };
1405
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
+ /**
1406
1414
  * Recursively walks the provided AST to collect all TypeScript type references that are found
1407
1415
  *
1408
1416
  * @param checker a {@link ts.TypeChecker} instance
@@ -1429,6 +1437,11 @@ const getAllTypeReferences = (checker, node) => {
1429
1437
  type: checker.getTypeFromTypeNode(typeRef)
1430
1438
  });
1431
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
+ });
1432
1445
  }
1433
1446
  return ts.forEachChild(currentNode, visit);
1434
1447
  };
@@ -1469,30 +1482,50 @@ const getTypeReferenceLocation = (typeName, type, sourceFile, checker, program)
1469
1482
  const importName = importElement.name;
1470
1483
  const originalTypeName = getOriginalTypeName(importName, checker);
1471
1484
  const importedAs = importElement.propertyName ? importElement.propertyName.getText() : typeName;
1472
- const typeDecl = findTypeWithName(importHomeModule, originalTypeName);
1473
- 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;
1474
1494
  return {
1475
1495
  location: "import",
1476
1496
  path: localImportPath,
1477
- id: addToLibrary(type, originalTypeName, checker, normalizePath(importHomeModule.fileName, false)),
1497
+ id: addToLibrary(type, originalTypeName, checker, normalizePath(typeSourceFile.fileName, false)),
1478
1498
  referenceLocation: importedAs
1479
1499
  };
1480
1500
  }
1481
1501
  }
1482
- 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
+ }
1483
1512
  const statementModifiers = retrieveTsModifiers(st);
1484
- 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);
1485
1514
  const isInterfaceDeclarationExported = ts.isInterfaceDeclaration(st) && isDeclarationExported(st);
1486
1515
  const isTypeAliasDeclarationExported = ts.isTypeAliasDeclaration(st) && isDeclarationExported(st);
1487
1516
  const isEnumDeclarationExported = ts.isEnumDeclaration(st) && isDeclarationExported(st);
1488
- const isTypeInExportDeclaration = ts.isExportDeclaration(st) && ts.isNamedExports(st.exportClause) && st.exportClause.elements.some((nee) => nee.name.getText() === typeName);
1489
- return isInterfaceDeclarationExported || isTypeAliasDeclarationExported || isEnumDeclarationExported || isTypeInExportDeclaration;
1490
- })) {
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) {
1491
1522
  const id = addToLibrary(type, typeName, checker, sourceFile.fileName);
1492
1523
  return {
1493
1524
  location: "local",
1494
1525
  path: sourceFile.fileName,
1495
- id
1526
+ id,
1527
+ ...localExport.isDefault ? { isDefault: true } : {},
1528
+ ...localExport.referenceLocation ? { referenceLocation: localExport.referenceLocation } : {}
1496
1529
  };
1497
1530
  }
1498
1531
  const defaultImportDeclaration = sourceFile.statements.find((st) => {
@@ -1502,19 +1535,19 @@ const getTypeReferenceLocation = (typeName, type, sourceFile, checker, program)
1502
1535
  });
1503
1536
  if (defaultImportDeclaration) {
1504
1537
  const localImportPath = defaultImportDeclaration.moduleSpecifier.text;
1505
- const options = program.getCompilerOptions();
1506
- const importHomeModule = getHomeModule(sourceFile, localImportPath, options, ts.createCompilerHost(options), program);
1507
- if (importHomeModule) {
1508
- if (importHomeModule.statements.find((st) => ts.isExportAssignment(st) && !st.isExportEquals && ts.isIdentifier(st.expression) && st.expression.getText() === typeName)) {
1509
- const typeDecl = findTypeWithName(importHomeModule, typeName);
1510
- type = checker.getTypeAtLocation(typeDecl);
1511
- return {
1512
- location: "import",
1513
- path: localImportPath,
1514
- id: addToLibrary(type, typeName, checker, normalizePath(importHomeModule.fileName, false)),
1515
- isDefault: true
1516
- };
1517
- }
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
+ };
1518
1551
  }
1519
1552
  }
1520
1553
  return {
@@ -1559,7 +1592,8 @@ const getTypeReferenceLocation = (typeName, type, sourceFile, checker, program)
1559
1592
  */
1560
1593
  const resolveType = (checker, type, typeNode) => {
1561
1594
  if (typeNode && ts.isArrayTypeNode(typeNode)) {
1562
- 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);
1563
1597
  return elementResolved.includes(" | ") ? `(${elementResolved})[]` : `${elementResolved}[]`;
1564
1598
  }
1565
1599
  const set = /* @__PURE__ */ new Set();
@@ -1613,13 +1647,18 @@ const parseDocsType = (checker, type, parts) => {
1613
1647
  const elemStr = sortedParts.join(" | ");
1614
1648
  parts.add(sortedParts.length > 1 ? `(${elemStr})[]` : `${elemStr}[]`);
1615
1649
  } else parts.add(typeToString(checker, type));
1616
- } else if (type.aliasSymbol) if (type.aliasTypeArguments && type.aliasTypeArguments.length > 0) type.aliasTypeArguments.forEach((argType) => {
1617
- parseDocsType(checker, argType, parts);
1618
- });
1619
- else if (type.aliasSymbol.declarations && type.aliasSymbol.declarations.length > 0) {
1620
- const aliasedType = checker.getTypeAtLocation(type.aliasSymbol.declarations[0]);
1621
- if (aliasedType && aliasedType !== type) parseDocsType(checker, aliasedType, parts);
1622
- 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 {
1623
1662
  const text = typeToString(checker, type);
1624
1663
  parts.add(text);
1625
1664
  }
@@ -1627,10 +1666,6 @@ const parseDocsType = (checker, type, parts) => {
1627
1666
  const text = typeToString(checker, type);
1628
1667
  parts.add(text);
1629
1668
  }
1630
- else {
1631
- const text = typeToString(checker, type);
1632
- parts.add(text);
1633
- }
1634
1669
  };
1635
1670
  /**
1636
1671
  * Retrieves a Stencil `Module` entity from the compiler context for a given TypeScript `SourceFile`
@@ -1658,7 +1693,8 @@ const getComponentMeta = (compilerCtx, tsSourceFile, node) => {
1658
1693
  if (meta) return meta;
1659
1694
  const moduleFile = getModuleFromSourceFile(compilerCtx, tsSourceFile);
1660
1695
  if (moduleFile != null && node.members != null) {
1661
- const tagName = getComponentTagName(node.members.filter(isStaticGetter));
1696
+ const staticMembers = node.members.filter(isStaticGetter);
1697
+ const tagName = getComponentTagName(staticMembers);
1662
1698
  if (typeof tagName === "string") return moduleFile.cmps.find((cmp) => cmp.tagName === tagName);
1663
1699
  }
1664
1700
  };
@@ -2100,7 +2136,8 @@ const generateAppDataModule = (build, config) => {
2100
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`;
2101
2137
  };
2102
2138
  const serializeCollectionManifest = (config, compilerCtx, buildCtx) => {
2103
- 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);
2104
2141
  buildFlags.hydrateClientSide = config.outputTargets.some(isOutputTargetSsr);
2105
2142
  const ldp = config.compat?.lightDomPatches ?? true;
2106
2143
  if (buildFlags.slotRelocation && ldp !== false) {
@@ -2146,10 +2183,11 @@ const serializeCollectionManifest = (config, compilerCtx, buildCtx) => {
2146
2183
  return collectionManifest;
2147
2184
  };
2148
2185
  const serializeCollectionDependencies = (compilerCtx) => {
2149
- return sortBy(compilerCtx.collections.map((c) => ({
2186
+ const collectionDeps = compilerCtx.collections.map((c) => ({
2150
2187
  name: c.collectionName,
2151
2188
  tags: flatOne(c.moduleFiles.map((m) => m.cmps)).map((cmp) => cmp.tagName).sort()
2152
- })), (item) => item.name);
2189
+ }));
2190
+ return sortBy(collectionDeps, (item) => item.name);
2153
2191
  };
2154
2192
  //#endregion
2155
2193
  //#region src/compiler/output-targets/copy/local-copy-tasks.ts
@@ -2158,8 +2196,10 @@ const getSrcAbsPath = (config, src) => {
2158
2196
  return join$2(config.srcDir, src);
2159
2197
  };
2160
2198
  const getDestAbsPath = (src, destAbsPath, destRelPath) => {
2161
- if (destRelPath) if (isAbsolute$1(destRelPath)) return destRelPath;
2162
- else return join$2(destAbsPath, destRelPath);
2199
+ if (destRelPath) {
2200
+ if (isAbsolute$1(destRelPath)) return destRelPath;
2201
+ else return join$2(destAbsPath, destRelPath);
2202
+ }
2163
2203
  if (isAbsolute$1(src)) throw new Error(`copy task, "dest" property must exist if "src" property is an absolute path: ${src}`);
2164
2204
  return destAbsPath;
2165
2205
  };
@@ -2353,6 +2393,7 @@ const setPackageVersionByContent = (pkgVersions, pkgContent) => {
2353
2393
  if (pkg.name && pkg.version) setPackageVersion(pkgVersions, pkg.name, pkg.version);
2354
2394
  } catch {}
2355
2395
  };
2396
+ const isNodeModulePath = (p) => normalizePath(p).split("/").includes("node_modules");
2356
2397
  const getModuleId = (orgImport) => {
2357
2398
  if (orgImport.startsWith("~")) orgImport = orgImport.substring(1);
2358
2399
  const splt = orgImport.split("/");
@@ -2444,6 +2485,54 @@ const createCustomResolverAsync = (sys, inMemoryFs, exts) => {
2444
2485
  //#endregion
2445
2486
  //#region src/compiler/style/style-utils.ts
2446
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
+ /**
2447
2536
  * Strip out comments from some CSS
2448
2537
  *
2449
2538
  * @param input the string we'd like to de-comment
@@ -2583,7 +2672,8 @@ const getCssImports = async (config, compilerCtx, buildCtx, filePath, styleText)
2583
2672
  cssImportData.filePath += `.${importeeExt}`;
2584
2673
  if (importeeExt === "scss") {
2585
2674
  const fileName = "_" + basename$1(cssImportData.filePath);
2586
- 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));
2587
2677
  }
2588
2678
  }
2589
2679
  if (cssImportData.filePath !== "") imports.push(cssImportData);
@@ -2634,44 +2724,7 @@ const isLocalCssImport$1 = (srcImport) => {
2634
2724
  const replaceImportDeclarations = (styleText, cssImports, isCssEntry) => {
2635
2725
  for (const cssImport of cssImports) if (isCssEntry) {
2636
2726
  if (typeof cssImport.styleText === "string") {
2637
- let replacement = cssImport.styleText;
2638
- if (cssImport.modifiers) {
2639
- let modifiers = cssImport.modifiers;
2640
- let layerName = "";
2641
- let supportsCondition = "";
2642
- let mediaQuery = "";
2643
- const layerMatch = modifiers.match(/layer\(([^)]+)\)/);
2644
- if (layerMatch) {
2645
- layerName = layerMatch[1].trim();
2646
- modifiers = modifiers.replace(/layer\([^)]+\)/, "").trim();
2647
- }
2648
- let depth = 0;
2649
- let startIdx = -1;
2650
- let endIdx = -1;
2651
- const supportsIdx = modifiers.indexOf("supports(");
2652
- if (supportsIdx !== -1) {
2653
- startIdx = supportsIdx + 9;
2654
- for (let i = startIdx; i < modifiers.length; i++) {
2655
- if (modifiers[i] === "(") depth++;
2656
- if (modifiers[i] === ")") {
2657
- if (depth === 0) {
2658
- endIdx = i;
2659
- break;
2660
- }
2661
- depth--;
2662
- }
2663
- }
2664
- if (endIdx !== -1) {
2665
- supportsCondition = modifiers.substring(startIdx, endIdx).trim();
2666
- modifiers = modifiers.substring(0, supportsIdx) + modifiers.substring(endIdx + 1);
2667
- modifiers = modifiers.trim();
2668
- }
2669
- }
2670
- mediaQuery = modifiers.trim();
2671
- if (layerName) replacement = `@layer ${layerName} {\n${replacement}\n}`;
2672
- if (mediaQuery) replacement = `@media ${mediaQuery} {\n${replacement}\n}`;
2673
- if (supportsCondition) replacement = `@supports (${supportsCondition}) {\n${replacement}\n}`;
2674
- }
2727
+ const replacement = wrapCssWithImportModifiers(cssImport.styleText, cssImport.modifiers);
2675
2728
  styleText = styleText.replace(cssImport.srcImport, replacement);
2676
2729
  }
2677
2730
  } else if (typeof cssImport.updatedImport === "string") styleText = styleText.replace(cssImport.srcImport, cssImport.updatedImport);
@@ -2725,7 +2778,8 @@ const runPluginTransforms = async (config, compilerCtx, buildCtx, id, cmp) => {
2725
2778
  cache: compilerCtx.cache,
2726
2779
  diagnostics: []
2727
2780
  };
2728
- const sourceText = await runPluginLoad(pluginCtx, await runPluginResolveId(pluginCtx, id));
2781
+ const resolvedId = await runPluginResolveId(pluginCtx, id);
2782
+ const sourceText = await runPluginLoad(pluginCtx, resolvedId);
2729
2783
  if (!isString$1(sourceText)) {
2730
2784
  const diagnostic = buildError(buildCtx.diagnostics);
2731
2785
  diagnostic.header = `Unable to find "${basename$1(id)}"`;
@@ -2739,15 +2793,17 @@ const runPluginTransforms = async (config, compilerCtx, buildCtx, id, cmp) => {
2739
2793
  };
2740
2794
  const isRawCssFile = transformResults.id.toLowerCase().endsWith(".css");
2741
2795
  const shouldParseCssDocs = cmp != null && config.outputTargets.some(isOutputTargetDocs);
2742
- if (isRawCssFile) if (shouldParseCssDocs && cmp != null) {
2743
- cmp.styleDocs = cmp.styleDocs || [];
2744
- const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, id, transformResults.code, cmp.styleDocs);
2745
- transformResults.code = cssParseResults.styleText;
2746
- transformResults.dependencies = cssParseResults.imports;
2747
- } else {
2748
- const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, id, transformResults.code);
2749
- transformResults.code = cssParseResults.styleText;
2750
- 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
+ }
2751
2807
  }
2752
2808
  for (const plugin of pluginCtx.config?.plugins ?? []) if (isFunction(plugin.transform)) try {
2753
2809
  let pluginTransformResults;
@@ -2755,29 +2811,33 @@ const runPluginTransforms = async (config, compilerCtx, buildCtx, id, cmp) => {
2755
2811
  if (results != null) {
2756
2812
  if (isFunction(results.then)) pluginTransformResults = await results;
2757
2813
  else pluginTransformResults = results;
2758
- if (pluginTransformResults != null) if (isString$1(pluginTransformResults)) transformResults.code = pluginTransformResults;
2759
- else {
2760
- if (isString$1(pluginTransformResults.code)) transformResults.code = pluginTransformResults.code;
2761
- if (isString$1(pluginTransformResults.id)) transformResults.id = pluginTransformResults.id;
2762
- /**
2763
- * add dependencies from plugin transform results, e.g. transformed sass files
2764
- */
2765
- 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
+ }
2766
2824
  }
2767
2825
  }
2768
2826
  } catch (e) {
2769
2827
  catchError(buildCtx.diagnostics, e);
2770
2828
  }
2771
2829
  buildCtx.diagnostics.push(...pluginCtx.diagnostics);
2772
- if (!isRawCssFile) if (shouldParseCssDocs && cmp != null) {
2773
- cmp.styleDocs = cmp.styleDocs || [];
2774
- const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, transformResults.id, transformResults.code, cmp.styleDocs);
2775
- transformResults.code = cssParseResults.styleText;
2776
- transformResults.dependencies.push(...getDependencySubset(cssParseResults.imports, transformResults.dependencies));
2777
- } else {
2778
- const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, transformResults.id, transformResults.code);
2779
- transformResults.code = cssParseResults.styleText;
2780
- 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
+ }
2781
2841
  }
2782
2842
  return transformResults;
2783
2843
  };
@@ -2808,13 +2868,15 @@ const runPluginTransformsEsmImports = async (config, compilerCtx, buildCtx, code
2808
2868
  if (results != null) {
2809
2869
  if (isFunction(results.then)) pluginTransformResults = await results;
2810
2870
  else pluginTransformResults = results;
2811
- if (pluginTransformResults != null) if (isString$1(pluginTransformResults)) transformResults.code = pluginTransformResults;
2812
- else {
2813
- if (isString$1(pluginTransformResults.code)) transformResults.code = pluginTransformResults.code;
2814
- if (isString$1(pluginTransformResults.id)) transformResults.id = pluginTransformResults.id;
2815
- if (Array.isArray(pluginTransformResults.dependencies)) {
2816
- const imports = pluginTransformResults.dependencies.filter((f) => !transformResults.dependencies.includes(f));
2817
- 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
+ }
2818
2880
  }
2819
2881
  }
2820
2882
  }
@@ -2860,8 +2922,8 @@ const optimizeCss$1 = async (config, compilerCtx, diagnostics, styleText, filePa
2860
2922
  };
2861
2923
  //#endregion
2862
2924
  //#region src/compiler/style/component-global-styles.ts
2863
- const STENCIL_GLOBALS_RE = /@import\s+(?:url\()?\s*['"]stencil-globals['"]\s*\)?\s*;?/g;
2864
- 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;
2865
2927
  const hasStencilGlobalsImport = (css) => css.includes("stencil-globals");
2866
2928
  const hasStencilHydrateImport = (css) => css.includes("stencil-hydrate");
2867
2929
  /**
@@ -2884,12 +2946,16 @@ const generateHydrateCss = (config, buildCtx) => {
2884
2946
  };
2885
2947
  /**
2886
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);`.
2887
2950
  * @param css the CSS string to process
2888
2951
  * @param config the Stencil configuration
2889
2952
  * @param buildCtx the current build context, used to get the list of components in the build
2890
2953
  * @returns the CSS string with `@import "stencil-hydrate"` replaced by generated styles
2891
2954
  */
2892
- 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
+ };
2893
2959
  /**
2894
2960
  * Collect and build all component-level globalStyle/globalStyleUrl CSS from the current build.
2895
2961
  * Results are cached per file path via the existing globalStyleCache.
@@ -2927,6 +2993,7 @@ const collectAndBuildComponentGlobalStyles = async (config, compilerCtx, buildCt
2927
2993
  * Replace `@import "stencil-globals"` in CSS with the collected component global styles.
2928
2994
  * Also registers component global style files as cssModuleImports of the global stylesheet
2929
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);`.
2930
2997
  *
2931
2998
  * @param css the CSS string to process
2932
2999
  * @param config the Stencil configuration
@@ -2943,7 +3010,7 @@ const resolveStencilGlobalsImport = async (css, config, compilerCtx, buildCtx, g
2943
3010
  for (const p of filePaths) if (!existing.includes(p)) existing.push(p);
2944
3011
  compilerCtx.cssModuleImports.set(globalStyleInputPath, existing);
2945
3012
  }
2946
- return css.replace(STENCIL_GLOBALS_RE, collectedCss);
3013
+ return css.replace(STENCIL_GLOBALS_RE, (_match, modifiers) => wrapCssWithImportModifiers(collectedCss, modifiers));
2947
3014
  };
2948
3015
  //#endregion
2949
3016
  //#region src/compiler/style/global-styles.ts
@@ -3464,7 +3531,8 @@ const getStencilInternalModule = (config, compilerExe, internalModule) => {
3464
3531
  moduleId: "@stencil/core",
3465
3532
  path: "runtime/" + internalModule
3466
3533
  }));
3467
- return normalizePath(join$2(dirname$1(compilerExe), "..", "runtime", internalModule));
3534
+ const compilerExeDir = dirname$1(compilerExe);
3535
+ return normalizePath(join$2(compilerExeDir, "..", "runtime", internalModule));
3468
3536
  };
3469
3537
  const getHydratedFlagHead = (h) => {
3470
3538
  let initial;
@@ -3516,7 +3584,8 @@ const getPackageJsonPath = (resolvedPath, importee) => {
3516
3584
  for (let i = 0; i < 10; i++) {
3517
3585
  currentPath = dirname$1(currentPath);
3518
3586
  const aBasename = basename$1(currentPath);
3519
- const bBasename = basename$1(dirname$1(currentPath));
3587
+ const upDir = dirname$1(currentPath);
3588
+ const bBasename = basename$1(upDir);
3520
3589
  if (aBasename === importee && bBasename === "node_modules") return join$2(currentPath, "package.json");
3521
3590
  }
3522
3591
  return null;
@@ -3565,7 +3634,7 @@ const FORMAT_TEXT_EXTS = [
3565
3634
  "vert"
3566
3635
  ];
3567
3636
  const FORMAT_URL_MIME = { svg: "image/svg+xml" };
3568
- const DATAURL_MAX_IMAGE_SIZE = 4 * 1024;
3637
+ const DATAURL_MAX_IMAGE_SIZE = 4096;
3569
3638
  const formatText = (code, filePath) => {
3570
3639
  const varName = createJsVarName(basename$1(filePath));
3571
3640
  return `const ${varName} = ${JSON.stringify(code)};export default ${varName};`;
@@ -3663,6 +3732,7 @@ const parseImportPath = (importPath) => {
3663
3732
  encapsulation: urlParams.get("encapsulation") || "none",
3664
3733
  mode: urlParams.get("mode") || "$"
3665
3734
  };
3735
+ else if (urlParams.has("stencil") && parsedPath.basename.endsWith(".css")) parsedPath.data = { encapsulation: "none" };
3666
3736
  } else if (parsedPath.basename.endsWith(".css")) parsedPath.data = { encapsulation: "none" };
3667
3737
  }
3668
3738
  return parsedPath;
@@ -3902,7 +3972,7 @@ const loaderPlugin = (entries = {}) => {
3902
3972
  };
3903
3973
  //#endregion
3904
3974
  //#region src/compiler/bundle/plugin-helper.ts
3905
- const builtIns = new Set([
3975
+ const builtIns = /* @__PURE__ */ new Set([
3906
3976
  "child_process",
3907
3977
  "cluster",
3908
3978
  "dgram",
@@ -4059,6 +4129,7 @@ const createModule = (staticSourceFile, staticSourceFileText, emitFilepath) => (
4059
4129
  hasSignalsImport: false,
4060
4130
  htmlAttrNames: [],
4061
4131
  htmlParts: [],
4132
+ htmlSlots: [],
4062
4133
  htmlTagNames: [],
4063
4134
  isCollectionDependency: false,
4064
4135
  isLegacy: false,
@@ -4096,7 +4167,8 @@ const typescriptPlugin = (compilerCtx, bundleOpts, config) => {
4096
4167
  */
4097
4168
  load(id) {
4098
4169
  if (isAbsolute$1(id)) {
4099
- const module = getModule(compilerCtx, normalizeFsPath(id));
4170
+ const fsFilePath = normalizeFsPath(id);
4171
+ const module = getModule(compilerCtx, fsFilePath);
4100
4172
  if (module) {
4101
4173
  if (!module.sourceMapFileText) return {
4102
4174
  code: module.staticSourceFileText,
@@ -4278,7 +4350,7 @@ const loadMinifyJsDiagnostics = (sourceText, diagnostics, error) => {
4278
4350
  }
4279
4351
  diagnostics.push(d);
4280
4352
  };
4281
- const MINIFY_CHAR_BREAK = new Set([
4353
+ const MINIFY_CHAR_BREAK = /* @__PURE__ */ new Set([
4282
4354
  " ",
4283
4355
  "=",
4284
4356
  ".",
@@ -4500,16 +4572,18 @@ const workerPlugin = (config, compilerCtx, buildCtx, platform, inlineWorkers) =>
4500
4572
  const workerEntryPath = getWorkerEntryPath(id);
4501
4573
  if (workerEntryPath != null) {
4502
4574
  const worker = await getWorker(config, compilerCtx, buildCtx, this, workersMap, workerEntryPath);
4503
- if (worker) if (inlineWorkers) return {
4504
- code: getInlineWorkerProxy(workerEntryPath, worker.workerMsgId, worker.exports),
4505
- map: { mappings: "" },
4506
- moduleSideEffects: false
4507
- };
4508
- else return {
4509
- code: getWorkerProxy(workerEntryPath, worker.exports),
4510
- map: { mappings: "" },
4511
- moduleSideEffects: false
4512
- };
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
+ }
4513
4587
  }
4514
4588
  return null;
4515
4589
  }
@@ -4808,7 +4882,8 @@ ${exportedMethods.map((exportedMethod) => {
4808
4882
  //#region src/compiler/bundle/bundle-output.ts
4809
4883
  const bundleOutput = async (config, compilerCtx, buildCtx, bundleOpts) => {
4810
4884
  try {
4811
- return await rolldown(getRolldownOptions(config, compilerCtx, buildCtx, bundleOpts));
4885
+ const rolldownOptions = getRolldownOptions(config, compilerCtx, buildCtx, bundleOpts);
4886
+ return await rolldown(rolldownOptions);
4812
4887
  } catch (e) {
4813
4888
  if (!buildCtx.hasError && isRolldownError(e)) loadRolldownDiagnostics(config, compilerCtx, buildCtx, e);
4814
4889
  }
@@ -5433,13 +5508,14 @@ const updateCjsStyleRequires = (transformOpts, tsSourceFile, moduleFile) => {
5433
5508
  return tsSourceFile;
5434
5509
  };
5435
5510
  const getStyleImportPath = (transformOpts, tsSourceFile, cmp, style, importPath) => {
5436
- return serializeImportPath({
5511
+ const importData = {
5437
5512
  importeePath: importPath,
5438
5513
  importerPath: tsSourceFile.fileName,
5439
5514
  tag: cmp.tagName,
5440
5515
  encapsulation: cmp.encapsulation,
5441
5516
  mode: style.modeName
5442
- }, transformOpts.styleImportData);
5517
+ };
5518
+ return serializeImportPath(importData, transformOpts.styleImportData);
5443
5519
  };
5444
5520
  //#endregion
5445
5521
  //#region src/compiler/transformers/add-static-style.ts
@@ -5479,8 +5555,10 @@ const addStaticStylePropertyToClass = (styleStatements, cmp, buildCtx) => {
5479
5555
  }
5480
5556
  };
5481
5557
  const getStyleLiteral = (cmp, buildCtx) => {
5482
- 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);
5483
- 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
+ }
5484
5562
  return null;
5485
5563
  };
5486
5564
  const getMultipleModeStyle = (cmp, styles, buildCtx) => {
@@ -5902,30 +5980,31 @@ const updateStencilCoreImports = (updatedCoreImportPath) => {
5902
5980
  /**
5903
5981
  * A set of imports which we don't want to remove from an output file
5904
5982
  */
5905
- const KEEP_IMPORTS = new Set([
5906
- "h",
5907
- "setMode",
5908
- "getMode",
5909
- "setPlatformHelpers",
5983
+ const KEEP_IMPORTS = /* @__PURE__ */ new Set([
5910
5984
  "Build",
5911
5985
  "Env",
5912
- "Host",
5913
5986
  "Fragment",
5987
+ "Host",
5988
+ "Mixin",
5989
+ "ReactiveControllerHost",
5990
+ "forceUpdate",
5991
+ "forceModeUpdate",
5914
5992
  "getAssetPath",
5915
- "writeTask",
5916
- "readTask",
5917
5993
  "getElement",
5918
- "getShadowRoot",
5919
- "forceUpdate",
5994
+ "getMode",
5920
5995
  "getRenderingRef",
5921
- "forceModeUpdate",
5996
+ "getShadowRoot",
5997
+ "h",
5998
+ "jsx",
5999
+ "jsxs",
6000
+ "readTask",
6001
+ "render",
5922
6002
  "setErrorHandler",
6003
+ "setMode",
6004
+ "setPlatformHelpers",
5923
6005
  "setTagTransformer",
5924
6006
  "transformTag",
5925
- "Mixin",
5926
- "jsx",
5927
- "jsxs",
5928
- "render"
6007
+ "writeTask"
5929
6008
  ]);
5930
6009
  //#endregion
5931
6010
  //#region src/compiler/app-core/bundle-app-core.ts
@@ -6109,7 +6188,8 @@ const writeLazyChunk = async (config, compilerCtx, buildCtx, rolldownResult, out
6109
6188
  };
6110
6189
  const writeLazyEntry = async (config, compilerCtx, buildCtx, rolldownResult, outputTargetType, destinations, lazyRuntimeData, sourceTarget, shouldMinify, isBrowserBuild) => {
6111
6190
  if (isBrowserBuild && ["loader"].includes(rolldownResult.entryKey)) return;
6112
- 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);
6113
6193
  await Promise.all(destinations.map((dst) => {
6114
6194
  const filePath = join$2(dst, rolldownResult.fileName);
6115
6195
  let fileCode = code;
@@ -6129,7 +6209,8 @@ const writeLazyEntry = async (config, compilerCtx, buildCtx, rolldownResult, out
6129
6209
  * @returns A stringified representation of the lazy bundles.
6130
6210
  */
6131
6211
  const formatLazyBundlesRuntimeMeta = (bundleModules) => {
6132
- return stringifyRuntimeData(bundleModules.slice().sort(sortBundleModules).map(formatLazyRuntimeBundle));
6212
+ const lazyBundles = bundleModules.slice().sort(sortBundleModules).map(formatLazyRuntimeBundle);
6213
+ return stringifyRuntimeData(lazyBundles);
6133
6214
  };
6134
6215
  /**
6135
6216
  * Formats a bundle module into a tuple of bundle ID and component metadata for use at runtime.
@@ -6305,7 +6386,8 @@ const generateCjs = async (config, compilerCtx, buildCtx, rolldownBuild, outputT
6305
6386
  if (config.compat.enableImportInjection) esmOpts.dynamicImportInCjs = false;
6306
6387
  const results = await generateRolldownOutput(rolldownBuild, esmOpts, config, buildCtx.entryModules);
6307
6388
  if (results != null) {
6308
- 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);
6309
6391
  await generateShortcuts$1(compilerCtx, results, cjsOutputs);
6310
6392
  }
6311
6393
  }
@@ -6340,7 +6422,8 @@ const generateEsm = async (config, compilerCtx, buildCtx, rolldownBuild, outputT
6340
6422
  const outputTargetType = esmOutputs[0].type;
6341
6423
  const output = await generateRolldownOutput(rolldownBuild, esmOpts, config, buildCtx.entryModules);
6342
6424
  if (output != null) {
6343
- 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);
6344
6427
  await generateShortcuts(compilerCtx, outputTargets, output);
6345
6428
  }
6346
6429
  }
@@ -6365,7 +6448,7 @@ const generateEsmBrowser = async (config, compilerCtx, buildCtx, rolldownBuild,
6365
6448
  const esmOutputs = outputTargets.filter((o) => !!o.esmDir && !!o.isBrowserBuild);
6366
6449
  if (esmOutputs.length) {
6367
6450
  const outputTargetType = esmOutputs[0].type;
6368
- const output = await generateRolldownOutput(rolldownBuild, {
6451
+ const esmOpts = {
6369
6452
  banner: generatePreamble(config),
6370
6453
  format: "es",
6371
6454
  entryFileNames: "[name].js",
@@ -6373,7 +6456,8 @@ const generateEsmBrowser = async (config, compilerCtx, buildCtx, rolldownBuild,
6373
6456
  assetFileNames: esmOutputs[0].hashFileNames ? "p-[hash][extname]" : "[name]-[hash][extname]",
6374
6457
  sourcemap: config.sourceMap,
6375
6458
  plugins: [lazyBundleIdPlugin(buildCtx, config, esmOutputs[0].hashFileNames ?? true, esmOutputs[0].hashedFileNameLength ?? 8, "", true)]
6376
- }, config, buildCtx.entryModules);
6459
+ };
6460
+ const output = await generateRolldownOutput(rolldownBuild, esmOpts, config, buildCtx.entryModules);
6377
6461
  if (output != null) {
6378
6462
  const es2017destinations = esmOutputs.map((o) => o.esmDir).filter((esmDir) => typeof esmDir === "string");
6379
6463
  buildCtx.esmBrowserComponentBundle = await generateLazyModules(config, compilerCtx, buildCtx, outputTargetType, es2017destinations, output, "es2017", true);
@@ -6416,15 +6500,18 @@ const generateLoader = async (compilerCtx, outputTargets) => {
6416
6500
  await Promise.all(outputTargets.map(async (o) => {
6417
6501
  if (!o.loaderDir || !o.esmDir || !o.typesDir) return;
6418
6502
  const loaderIndexJs = join$2(o.loaderDir, "index.js");
6419
- 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);
6420
6505
  await compilerCtx.fs.writeFile(loaderIndexJs, `export * from '${relativeEsmLoader}';\n`, { outputTargetType: o.type });
6421
6506
  if (o.cjsDir) {
6422
6507
  const loaderIndexCjs = join$2(o.loaderDir, "index.cjs");
6423
- 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);
6424
6510
  await compilerCtx.fs.writeFile(loaderIndexCjs, `module.exports = require('${relativeCjsLoader}');\n`, { outputTargetType: o.type });
6425
6511
  }
6426
6512
  const loaderIndexDts = join$2(o.loaderDir, "index.d.ts");
6427
- 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);
6428
6515
  await compilerCtx.fs.writeFile(loaderIndexDts, `export * from '${relativeDtsPath}';\n`, { outputTargetType: o.type });
6429
6516
  }));
6430
6517
  };
@@ -6647,7 +6734,8 @@ const canSkipAssetsCopy = (compilerCtx, entryModules, filesChanged) => {
6647
6734
  entryModules.forEach((entryModule) => {
6648
6735
  entryModule.cmps.forEach((cmp) => {
6649
6736
  if (cmp.assetsDirs != null) cmp.assetsDirs.forEach((assetsDir) => {
6650
- if (changedFileDirPath === normalizePath(assetsDir.absolutePath)) {
6737
+ const assetDirPath = normalizePath(assetsDir.absolutePath);
6738
+ if (changedFileDirPath === assetDirPath) {
6651
6739
  shouldSkipAssetsCopy = false;
6652
6740
  return;
6653
6741
  }
@@ -6683,7 +6771,8 @@ const outputAssets = async (config, compilerCtx, buildCtx) => {
6683
6771
  allCopyTasks.push(...copyTasks);
6684
6772
  }
6685
6773
  for (const wwwTarget of wwwTargets) {
6686
- 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);
6687
6776
  allCopyTasks.push(...copyTasks);
6688
6777
  }
6689
6778
  if (allCopyTasks.length > 0) {
@@ -6912,6 +7001,7 @@ const generateDocData = async (config, compilerCtx, buildCtx) => {
6912
7001
  typescriptVersion: versions.typescript
6913
7002
  },
6914
7003
  components: await getDocsComponents(config, compilerCtx, buildCtx),
7004
+ usage: await generateUsages(compilerCtx, normalizePath(join$2(config.srcDir, "usage"))),
6915
7005
  typeLibrary
6916
7006
  };
6917
7007
  };
@@ -6934,7 +7024,7 @@ function findSupplementalPublicTypes(outputTargets) {
6934
7024
  * @returns the derived metadata
6935
7025
  */
6936
7026
  const getDocsComponents = async (config, compilerCtx, buildCtx) => {
6937
- return sortBy(flatOne(await Promise.all(buildCtx.moduleFiles.map(async (moduleFile) => {
7027
+ const results = await Promise.all(buildCtx.moduleFiles.map(async (moduleFile) => {
6938
7028
  const filePath = moduleFile.sourceFilePath;
6939
7029
  const dirPath = normalizePath(dirname$1(filePath));
6940
7030
  const readmePath = normalizePath(join$2(dirPath, "readme.md"));
@@ -6962,12 +7052,13 @@ const getDocsComponents = async (config, compilerCtx, buildCtx) => {
6962
7052
  methods: getDocsMethods(cmp.methods),
6963
7053
  events: getDocsEvents(cmp.events),
6964
7054
  styles: getDocsStyles(cmp),
6965
- slots: getDocsSlots(cmp.docs.tags),
7055
+ slots: getDocsSlots(cmp.htmlSlots, cmp.docs.tags),
6966
7056
  parts: getDocsParts(cmp.htmlParts, cmp.docs.tags),
6967
7057
  customStates: getDocsCustomStates(cmp),
6968
7058
  listeners: getDocsListeners(cmp.listeners)
6969
7059
  }));
6970
- }))), (cmp) => cmp.tag);
7060
+ }));
7061
+ return sortBy(flatOne(results), (cmp) => cmp.tag);
6971
7062
  };
6972
7063
  const buildDocsDepGraph = (cmp, cmps) => {
6973
7064
  const dependencies = {};
@@ -7154,11 +7245,17 @@ const getDocsDeprecationText = (tags) => {
7154
7245
  const deprecation = tags.find((t) => t.name === "deprecated");
7155
7246
  if (deprecation) return deprecation.text || "";
7156
7247
  };
7157
- const getDocsSlots = (tags) => {
7158
- 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]) => ({
7159
7251
  name,
7160
7252
  docs
7161
- })), (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);
7162
7259
  };
7163
7260
  const getDocsParts = (vdom, tags) => {
7164
7261
  const docsParts = getNameText("part", tags).map(([name, docs]) => ({
@@ -7224,7 +7321,7 @@ const cmpMetaToDocsComponent = (cmp, filePath, rootDir = process.cwd()) => {
7224
7321
  methods: getDocsMethods(cmp.methods ?? []),
7225
7322
  events: getDocsEvents(cmp.events ?? []),
7226
7323
  styles: getDocsStyles(cmp),
7227
- slots: getDocsSlots(docs.tags),
7324
+ slots: getDocsSlots(cmp.htmlSlots ?? [], docs.tags),
7228
7325
  parts: getDocsParts(cmp.htmlParts ?? [], docs.tags),
7229
7326
  customStates: getDocsCustomStates(cmp),
7230
7327
  listeners: getDocsListeners(cmp.listeners ?? [])
@@ -7333,63 +7430,552 @@ const outputCustom = async (config, compilerCtx, buildCtx) => {
7333
7430
  }));
7334
7431
  };
7335
7432
  //#endregion
7336
- //#region src/compiler/docs/cem/index.ts
7337
- /**
7338
- * Generate Custom Elements Manifest (custom-elements.json) output
7339
- * conforming to the Custom Elements Manifest specification.
7340
- * @see https://github.com/webcomponents/custom-elements-manifest
7341
- *
7342
- * @param compilerCtx the current compiler context
7343
- * @param docsData the generated docs data from Stencil components
7344
- * @param outputTargets the output targets configured for the build
7345
- */
7346
- const generateCustomElementsManifestDocs = async (compilerCtx, docsData, outputTargets) => {
7347
- const cemOutputTargets = outputTargets.filter(isOutputTargetDocsCustomElementsManifest);
7348
- if (cemOutputTargets.length === 0) return;
7349
- const manifest = generateManifest(docsData);
7350
- const jsonContent = JSON.stringify(manifest, null, 2);
7351
- 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;
7352
7449
  };
7353
- /**
7354
- * Generate the Custom Elements Manifest from Stencil docs data
7355
- * @param docsData the generated docs data
7356
- * @returns the Custom Elements Manifest object
7357
- */
7358
- const generateManifest = (docsData) => {
7359
- const componentsByFile = /* @__PURE__ */ new Map();
7360
- for (const component of docsData.components) {
7361
- const filePath = component.filePath;
7362
- if (!componentsByFile.has(filePath)) componentsByFile.set(filePath, []);
7363
- 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);
7364
7576
  }
7365
- const modules = [];
7366
- for (const [filePath, components] of componentsByFile) {
7367
- const declarations = components.map((component) => componentToDeclaration(component));
7368
- const exports = components.flatMap((component) => {
7369
- const className = dashToPascalCase(component.tag);
7370
- return [{
7371
- kind: "js",
7372
- name: className,
7373
- declaration: { name: className }
7374
- }, {
7375
- kind: "custom-element-definition",
7376
- name: component.tag,
7377
- declaration: { name: className }
7378
- }];
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);
7379
7585
  });
7380
- modules.push({
7381
- kind: "javascript-module",
7382
- path: filePath,
7383
- declarations,
7384
- exports
7586
+ this.rows.push({
7587
+ columns: colData,
7588
+ isHeader
7385
7589
  });
7386
7590
  }
7387
- return {
7388
- schemaVersion: "2.1.0",
7389
- modules
7390
- };
7591
+ toMarkdown() {
7592
+ return createTable(this.rows);
7593
+ }
7391
7594
  };
7392
- /**
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
+ /**
7393
7979
  * Convert Stencil's ComponentCompilerTypeReferences to CEM TypeReference array
7394
7980
  * @param references Stencil's type references map
7395
7981
  * @returns CEM TypeReference array
@@ -7570,141 +8156,13 @@ export default _default;
7570
8156
  deprecation: cmp.deprecation
7571
8157
  }))
7572
8158
  };
7573
- const jsonContent = JSON.stringify(json, null, 2);
7574
- await Promise.all(jsonOutputTargets.map((jsonOutput) => {
7575
- return writeDocsOutput(compilerCtx, jsonOutput, jsonContent, typesContent);
7576
- }));
7577
- };
7578
- const writeDocsOutput = async (compilerCtx, jsonOutput, jsonContent, typesContent) => {
7579
- return Promise.all([compilerCtx.fs.writeFile(jsonOutput.file, jsonContent), jsonOutput.typesFile ? compilerCtx.fs.writeFile(jsonOutput.typesFile, typesContent) : Promise.resolve()]);
7580
- };
7581
- //#endregion
7582
- //#region src/compiler/docs/readme/docs-util.ts
7583
- var MarkdownTable = class {
7584
- rows = [];
7585
- addHeader(data) {
7586
- this.addRow(data, true);
7587
- }
7588
- addRow(data, isHeader = false) {
7589
- const colData = [];
7590
- data.forEach((text) => {
7591
- const col = {
7592
- text: escapeMarkdownTableColumn(text),
7593
- width: text.length
7594
- };
7595
- colData.push(col);
7596
- });
7597
- this.rows.push({
7598
- columns: colData,
7599
- isHeader
7600
- });
7601
- }
7602
- toMarkdown() {
7603
- return createTable(this.rows);
7604
- }
7605
- };
7606
- const escapeMarkdownTableColumn = (text) => {
7607
- text = text.replace(/\r?\n/g, " ");
7608
- text = text.replace(/\|/g, "\\|");
7609
- return text;
7610
- };
7611
- const createTable = (rows) => {
7612
- const content = [];
7613
- if (rows.length === 0) return content;
7614
- normalizeColumCount(rows);
7615
- normalizeColumnWidth(rows);
7616
- const th = rows.find((r) => r.isHeader);
7617
- if (th) {
7618
- const headerRow = createRow(th);
7619
- content.push(headerRow);
7620
- content.push(createBorder(th));
7621
- }
7622
- rows.filter((r) => !r.isHeader).forEach((td) => {
7623
- content.push(createRow(td));
7624
- });
7625
- return content;
7626
- };
7627
- const createBorder = (th) => {
7628
- const border = {
7629
- columns: [],
7630
- isHeader: false
7631
- };
7632
- th.columns.forEach((c) => {
7633
- const borderCol = {
7634
- text: "",
7635
- width: c.width
7636
- };
7637
- while (borderCol.text.length < borderCol.width) borderCol.text += "-";
7638
- border.columns.push(borderCol);
7639
- });
7640
- return createRow(border);
7641
- };
7642
- const createRow = (row) => {
7643
- const content = ["| "];
7644
- row.columns.forEach((c) => {
7645
- content.push(c.text);
7646
- content.push(" | ");
7647
- });
7648
- return content.join("").trim();
7649
- };
7650
- const normalizeColumCount = (rows) => {
7651
- let columnCount = 0;
7652
- rows.forEach((r) => {
7653
- if (r.columns.length > columnCount) columnCount = r.columns.length;
7654
- });
7655
- rows.forEach((r) => {
7656
- while (r.columns.length < columnCount) r.columns.push({
7657
- text: ``,
7658
- width: 0
7659
- });
7660
- });
7661
- };
7662
- const normalizeColumnWidth = (rows) => {
7663
- const columnCount = rows[0].columns.length;
7664
- for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) {
7665
- let longestText = 0;
7666
- rows.forEach((r) => {
7667
- const col = r.columns[columnIndex];
7668
- if (col.text.length > longestText) longestText = col.text.length;
7669
- });
7670
- rows.forEach((r) => {
7671
- const col = r.columns[columnIndex];
7672
- col.width = longestText;
7673
- while (col.text.length < longestText) col.text += " ";
7674
- });
7675
- }
7676
- };
7677
- /**
7678
- * Checks if a given string is a valid hexadecimal color representation.
7679
- *
7680
- * @param str - The string to be checked.
7681
- * @returns `true` if the string is a valid hex color (e.g., '#FF00AA', '#f0f'), `false` otherwise.
7682
- *
7683
- * @example
7684
- * isHexColor('#FF00AA'); // true
7685
- * isHexColor('#f0f'); // true
7686
- * isHexColor('#abcde'); // false (too many characters)
7687
- * isHexColor('FF00AA'); // false (missing #)
7688
- */
7689
- const isHexColor = (str) => {
7690
- return /^#([0-9A-Fa-f]{3}){1,2}$/.test(str);
7691
- };
7692
- //#endregion
7693
- //#region src/compiler/docs/readme/markdown-css-props.ts
7694
- const stylesToMarkdown = (styles) => {
7695
- const content = [];
7696
- if (styles.length === 0) return content;
7697
- content.push(`## CSS Custom Properties`);
7698
- content.push(``);
7699
- const table = new MarkdownTable();
7700
- table.addHeader(["Name", "Description"]);
7701
- styles.forEach((style) => {
7702
- table.addRow([`\`${style.name}\``, style.docs]);
7703
- });
7704
- content.push(...table.toMarkdown());
7705
- content.push(``);
7706
- content.push(``);
7707
- return content;
8159
+ const jsonContent = JSON.stringify(json, null, 2);
8160
+ await Promise.all(jsonOutputTargets.map((jsonOutput) => {
8161
+ return writeDocsOutput(compilerCtx, jsonOutput, jsonContent, typesContent);
8162
+ }));
8163
+ };
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()]);
7708
8166
  };
7709
8167
  //#endregion
7710
8168
  //#region src/compiler/docs/readme/markdown-custom-states.ts
@@ -7778,220 +8236,6 @@ const getCmpLink = (from, to, cmps) => {
7778
8236
  return to;
7779
8237
  };
7780
8238
  //#endregion
7781
- //#region src/compiler/docs/readme/markdown-events.ts
7782
- const eventsToMarkdown = (events) => {
7783
- const content = [];
7784
- if (events.length === 0) return content;
7785
- content.push(`## Events`);
7786
- content.push(``);
7787
- const table = new MarkdownTable();
7788
- table.addHeader([
7789
- "Event",
7790
- "Description",
7791
- "Type"
7792
- ]);
7793
- events.forEach((ev) => {
7794
- table.addRow([
7795
- `\`${ev.event}\``,
7796
- getDocsField$2(ev),
7797
- `\`CustomEvent<${ev.detail}>\``
7798
- ]);
7799
- });
7800
- content.push(...table.toMarkdown());
7801
- content.push(``);
7802
- content.push(``);
7803
- return content;
7804
- };
7805
- const getDocsField$2 = (prop) => {
7806
- return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
7807
- };
7808
- //#endregion
7809
- //#region src/compiler/docs/readme/markdown-methods.ts
7810
- const methodsToMarkdown = (methods) => {
7811
- const content = [];
7812
- if (methods.length === 0) return content;
7813
- content.push(`## Methods`);
7814
- content.push(``);
7815
- methods.forEach((method) => {
7816
- content.push(`### \`${method.signature}\``);
7817
- content.push(``);
7818
- content.push(getDocsField$1(method));
7819
- content.push(``);
7820
- if (method.parameters.length > 0) {
7821
- const parmsTable = new MarkdownTable();
7822
- parmsTable.addHeader([
7823
- "Name",
7824
- "Type",
7825
- "Description"
7826
- ]);
7827
- method.parameters.forEach(({ name, type, docs }) => {
7828
- parmsTable.addRow([
7829
- "`" + name + "`",
7830
- "`" + type + "`",
7831
- docs
7832
- ]);
7833
- });
7834
- content.push(`#### Parameters`);
7835
- content.push(``);
7836
- content.push(...parmsTable.toMarkdown());
7837
- content.push(``);
7838
- }
7839
- if (method.returns) {
7840
- content.push(`#### Returns`);
7841
- content.push(``);
7842
- content.push(`Type: \`${method.returns.type}\``);
7843
- content.push(``);
7844
- content.push(method.returns.docs);
7845
- content.push(``);
7846
- }
7847
- });
7848
- content.push(``);
7849
- return content;
7850
- };
7851
- const getDocsField$1 = (prop) => {
7852
- return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
7853
- };
7854
- //#endregion
7855
- //#region src/compiler/docs/readme/markdown-overview.ts
7856
- /**
7857
- * Generate an 'Overview' section for a markdown file
7858
- * @param overview a component-level comment string to place in a markdown file
7859
- * @returns The generated Overview section. If the provided overview is empty, return an empty list
7860
- */
7861
- const overviewToMarkdown = (overview) => {
7862
- if (!overview) return [];
7863
- const content = [];
7864
- content.push(`## Overview`);
7865
- content.push("");
7866
- content.push(`${overview.trim()}`);
7867
- content.push("");
7868
- return content;
7869
- };
7870
- //#endregion
7871
- //#region src/compiler/docs/readme/markdown-parts.ts
7872
- /**
7873
- * Converts a list of Shadow Parts metadata to a table written in Markdown
7874
- * @param parts the Shadow parts metadata to convert
7875
- * @returns a list of strings that make up the Markdown table
7876
- */
7877
- const partsToMarkdown = (parts) => {
7878
- const content = [];
7879
- if (parts.length === 0) return content;
7880
- content.push(`## Shadow Parts`);
7881
- content.push(``);
7882
- const table = new MarkdownTable();
7883
- table.addHeader(["Part", "Description"]);
7884
- parts.forEach((style) => {
7885
- table.addRow([style.name === "" ? "" : `\`"${style.name}"\``, style.docs]);
7886
- });
7887
- content.push(...table.toMarkdown());
7888
- content.push(``);
7889
- content.push(``);
7890
- return content;
7891
- };
7892
- //#endregion
7893
- //#region src/compiler/docs/readme/markdown-props.ts
7894
- const propsToMarkdown = (props) => {
7895
- const content = [];
7896
- if (props.length === 0) return content;
7897
- content.push(`## Properties`);
7898
- content.push(``);
7899
- const table = new MarkdownTable();
7900
- table.addHeader([
7901
- "Property",
7902
- "Attribute",
7903
- "Description",
7904
- "Type",
7905
- "Default"
7906
- ]);
7907
- props.forEach((prop) => {
7908
- table.addRow([
7909
- getPropertyField(prop),
7910
- getAttributeField(prop),
7911
- getDocsField(prop),
7912
- getTypeField(prop),
7913
- getDefaultValueField(prop)
7914
- ]);
7915
- });
7916
- content.push(...table.toMarkdown());
7917
- content.push(``);
7918
- content.push(``);
7919
- return content;
7920
- };
7921
- const getPropertyField = (prop) => {
7922
- return `\`${prop.name}\`${prop.required ? " _(required)_" : ""}`;
7923
- };
7924
- const getAttributeField = (prop) => {
7925
- return prop.attr ? `\`${prop.attr}\`` : "--";
7926
- };
7927
- const getDocsField = (prop) => {
7928
- return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
7929
- };
7930
- const getTypeField = (prop) => {
7931
- return prop.type.includes("`") ? `\`\` ${prop.type} \`\`` : `\`${prop.type}\``;
7932
- };
7933
- const getDefaultValueField = (prop) => {
7934
- return prop.default?.includes("`") ? `\`\` ${prop.default} \`\`` : `\`${prop.default}\``;
7935
- };
7936
- //#endregion
7937
- //#region src/compiler/docs/readme/markdown-slots.ts
7938
- /**
7939
- * Converts a list of Slots metadata to a table written in Markdown
7940
- * @param slots the Slots metadata to convert
7941
- * @returns a list of strings that make up the Markdown table
7942
- */
7943
- const slotsToMarkdown = (slots) => {
7944
- const content = [];
7945
- if (slots.length === 0) return content;
7946
- content.push(`## Slots`);
7947
- content.push(``);
7948
- const table = new MarkdownTable();
7949
- table.addHeader(["Slot", "Description"]);
7950
- slots.forEach((style) => {
7951
- table.addRow([style.name === "" ? "" : `\`"${style.name}"\``, style.docs]);
7952
- });
7953
- content.push(...table.toMarkdown());
7954
- content.push(``);
7955
- content.push(``);
7956
- return content;
7957
- };
7958
- //#endregion
7959
- //#region src/compiler/docs/readme/markdown-usage.ts
7960
- const usageToMarkdown = (usages) => {
7961
- const content = [];
7962
- const merged = mergeUsages(usages);
7963
- if (merged.length === 0) return content;
7964
- content.push(`## Usage`);
7965
- merged.forEach(({ name, text }) => {
7966
- content.push("");
7967
- content.push(`### ${toTitleCase(name)}`);
7968
- content.push("");
7969
- content.push(text);
7970
- content.push("");
7971
- });
7972
- content.push("");
7973
- content.push("");
7974
- return content;
7975
- };
7976
- const mergeUsages = (usages) => {
7977
- const keys = Object.keys(usages);
7978
- const map = /* @__PURE__ */ new Map();
7979
- keys.forEach((key) => {
7980
- const usage = usages[key].trim();
7981
- const array = map.get(usage) || [];
7982
- array.push(key);
7983
- map.set(usage, array);
7984
- });
7985
- const merged = [];
7986
- map.forEach((value, key) => {
7987
- merged.push({
7988
- name: value.join(" / "),
7989
- text: key
7990
- });
7991
- });
7992
- return merged;
7993
- };
7994
- //#endregion
7995
8239
  //#region src/compiler/docs/readme/output-docs.ts
7996
8240
  /**
7997
8241
  * Generate a README for a given component and write it to disk.
@@ -8017,7 +8261,8 @@ const generateReadme = async (config, compilerCtx, readmeOutputs, docsData, cmps
8017
8261
  if (readmeOutput.dir) {
8018
8262
  const relativeReadmePath = relative$1(config.srcDir, docsData.readmePath);
8019
8263
  const readmeOutputPath = join$2(readmeOutput.dir, relativeReadmePath);
8020
- 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);
8021
8266
  if ((await compilerCtx.fs.readFile(readmeOutputPath))?.replace(/\r/g, "") === readmeContent.replace(/\r/g, "")) return;
8022
8267
  await compilerCtx.fs.writeFile(readmeOutputPath, readmeContent);
8023
8268
  if (isUpdate) config.logger.info(`updated readme docs: ${docsData.tag}`);
@@ -8046,7 +8291,8 @@ const generateMergedReadme = async (config, compilerCtx, readmeOutputs, cmps, al
8046
8291
  if (readmeOutput.dir) {
8047
8292
  const relativeReadmePath = relative$1(config.srcDir, primaryCmp.readmePath);
8048
8293
  const readmeOutputPath = join$2(readmeOutput.dir, relativeReadmePath);
8049
- 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);
8050
8296
  if ((await compilerCtx.fs.readFile(readmeOutputPath))?.replace(/\r/g, "") === readmeContent.replace(/\r/g, "")) return;
8051
8297
  await compilerCtx.fs.writeFile(readmeOutputPath, readmeContent);
8052
8298
  const tags = cmps.map((c) => c.tag).join(", ");
@@ -8102,8 +8348,8 @@ const generateComponentBody = (cmp, cmps, readmeOutput, config) => {
8102
8348
  ...getDocsDeprecation(cmp),
8103
8349
  ...overviewToMarkdown(cmp.overview),
8104
8350
  ...usageToMarkdown(cmp.usage),
8105
- ...propsToMarkdown(cmp.props),
8106
- ...eventsToMarkdown(cmp.events),
8351
+ ...propsToMarkdown(cmp.props, cmp, readmeOutput.customColumns?.props),
8352
+ ...eventsToMarkdown(cmp.events, cmp, readmeOutput.customColumns?.events),
8107
8353
  ...methodsToMarkdown(cmp.methods),
8108
8354
  ...slotsToMarkdown(cmp.slots),
8109
8355
  ...partsToMarkdown(cmp.parts),
@@ -8303,14 +8549,15 @@ const serializeAttribute = (prop) => {
8303
8549
  * @param buildCtx the build context for the current Stencil task run
8304
8550
  */
8305
8551
  const outputDocs = async (config, compilerCtx, buildCtx) => {
8306
- 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);
8307
8553
  if (docsOutputTargets.length === 0) return;
8308
8554
  await buildCtx.stylesPromise;
8309
8555
  const docsData = await generateDocData(config, compilerCtx, buildCtx);
8310
- 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) => {
8311
8557
  if (component.styles.length === 0) {
8312
8558
  const readmeDir = docsOutputTargets.find(isOutputTargetDocsReadme)?.dir || config.srcDir;
8313
- 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);
8314
8561
  if (existingCssProps) component.styles = existingCssProps;
8315
8562
  }
8316
8563
  }));
@@ -8319,7 +8566,8 @@ const outputDocs = async (config, compilerCtx, buildCtx) => {
8319
8566
  generateJsonDocs(config, compilerCtx, docsData, docsOutputTargets),
8320
8567
  generateVscodeDocs(compilerCtx, docsData, docsOutputTargets),
8321
8568
  generateCustomDocs(config, docsData, docsOutputTargets),
8322
- generateCustomElementsManifestDocs(compilerCtx, docsData, docsOutputTargets)
8569
+ generateCustomElementsManifestDocs(compilerCtx, docsData, docsOutputTargets),
8570
+ generateAgentSkillDocs(compilerCtx, docsData, docsOutputTargets)
8323
8571
  ]);
8324
8572
  };
8325
8573
  //#endregion
@@ -8353,7 +8601,8 @@ const outputGlobalStyle = async (config, compilerCtx, buildCtx) => {
8353
8601
  const primaryPath = join$2(outputTarget.dir, outputTarget.fileName);
8354
8602
  writePromises.push(compilerCtx.fs.writeFile(primaryPath, css, { outputTargetType: outputTarget.type }));
8355
8603
  if (outputTarget.copyToLoaderBrowser && loaderBundleTargets.length > 0) for (const loaderTarget of loaderBundleTargets) {
8356
- 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);
8357
8606
  writePromises.push(compilerCtx.fs.writeFile(compatPath, css));
8358
8607
  }
8359
8608
  for (const wwwTarget of wwwTargets) {
@@ -8403,7 +8652,8 @@ const generateStandaloneTypesOutput = async (config, compilerCtx, buildCtx, type
8403
8652
  ...components.map((component) => {
8404
8653
  const exportName = dashToPascalCase(component.tagName);
8405
8654
  const importName = component.componentClassName;
8406
- 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);
8407
8657
  const defineFunctionExportName = `defineCustomElement${exportName}`;
8408
8658
  const localComponentTypeDefFilePath = `./${component.tagName}`;
8409
8659
  return [`export { ${importName} as ${exportName} } from '${componentDTSPath.startsWith(".") ? componentDTSPath : "./" + componentDTSPath}';`, `export { defineCustomElement as ${defineFunctionExportName} } from '${localComponentTypeDefFilePath}';`].join("\n");
@@ -8474,8 +8724,9 @@ const generateCustomElementType = (componentsDtsRelPath, cmp) => {
8474
8724
  const tagNameAsPascal = dashToPascalCase(cmp.tagName);
8475
8725
  return [
8476
8726
  `import type { Components, JSX } from "${componentsDtsRelPath}";`,
8727
+ `import type { HTMLStencilElement } from "@stencil/core/runtime";`,
8477
8728
  ``,
8478
- `interface ${tagNameAsPascal} extends Components.${tagNameAsPascal}, HTMLElement {}`,
8729
+ `interface ${tagNameAsPascal} extends Components.${tagNameAsPascal}, HTMLStencilElement {}`,
8479
8730
  `export const ${tagNameAsPascal}: {`,
8480
8731
  ` prototype: ${tagNameAsPascal};`,
8481
8732
  ` new (): ${tagNameAsPascal};`,
@@ -8500,7 +8751,7 @@ const relDts = (fromPath, dtsPath) => {
8500
8751
  };
8501
8752
  //#endregion
8502
8753
  //#region src/compiler/types/constants.ts
8503
- const HTML_ELEMENT_METHODS = new Set([
8754
+ const HTML_ELEMENT_METHODS = /* @__PURE__ */ new Set([
8504
8755
  "attachInternals",
8505
8756
  "blur",
8506
8757
  "click",
@@ -8593,7 +8844,9 @@ const HTML_ELEMENT_METHODS = new Set([
8593
8844
  * @returns the updated type declaration file contents
8594
8845
  */
8595
8846
  const updateStencilTypesImports = (typesDir, dtsFilePath, dtsContent) => {
8596
- 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);
8597
8850
  if (!coreDtsPath.startsWith(".")) coreDtsPath = `./${coreDtsPath}`;
8598
8851
  coreDtsPath = normalizePath(coreDtsPath);
8599
8852
  if (dtsContent.includes("@stencil/core")) {
@@ -8731,7 +8984,8 @@ const CORE_DTS = `${CORE_FILENAME}.d.ts`;
8731
8984
  * @returns additional types information to add event listener method overloads for component's html element type
8732
8985
  */
8733
8986
  const generateEventListenerTypes = (cmp, typeImportData) => {
8734
- const tagNameAsPascal = dashToPascalCase(cmp.tagName.toLowerCase());
8987
+ const tagName = cmp.tagName.toLowerCase();
8988
+ const tagNameAsPascal = dashToPascalCase(tagName);
8735
8989
  const htmlElementName = `HTML${tagNameAsPascal}Element`;
8736
8990
  const cmpEventInterface = `${tagNameAsPascal}CustomEvent`;
8737
8991
  const htmlElementEventMapName = `${htmlElementName}EventMap`;
@@ -8797,9 +9051,11 @@ const getEventGenericType = (cmpEvent, typeImportData, componentSourcePath) => {
8797
9051
  */
8798
9052
  const generateEventTypes = (cmpMeta, typeImportData, cmpClassName) => {
8799
9053
  return cmpMeta.events.map((cmpEvent) => {
9054
+ const name = `on${toTitleCase(cmpEvent.name)}`;
9055
+ const cmpEventDetailInterface = `${cmpClassName}CustomEvent`;
8800
9056
  return {
8801
- name: `on${toTitleCase(cmpEvent.name)}`,
8802
- type: getEventType$1(cmpEvent, `${cmpClassName}CustomEvent`, typeImportData, cmpMeta.sourceFilePath),
9057
+ name,
9058
+ type: getEventType$1(cmpEvent, cmpEventDetailInterface, typeImportData, cmpMeta.sourceFilePath),
8803
9059
  optional: false,
8804
9060
  required: false,
8805
9061
  internal: cmpEvent.internal,
@@ -9210,6 +9466,12 @@ const updateImportReferenceFactory = (typeCounts, filePath, config) => {
9210
9466
  //#endregion
9211
9467
  //#region src/compiler/types/generate-app-types.ts
9212
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
+ /**
9213
9475
  * Generates and writes a `components.d.ts` file to disk. This file may be written to the `src` directory of a project,
9214
9476
  * or be written to a directory that is meant to be distributed.
9215
9477
  * @param config the Stencil configuration associated with the project being compiled
@@ -9273,20 +9535,26 @@ const generateComponentTypesFile = (config, buildCtx, areTypesInternal) => {
9273
9535
  const typeData = typeImportData[filePath];
9274
9536
  let importFilePath = filePath;
9275
9537
  if (isAbsolute$1(filePath)) importFilePath = normalizePath("./" + relative$1(config.srcDir, filePath)).replace(/\.(tsx|ts)$/, "");
9276
- const hasDefaultImport = typeData.some((td) => td.isDefault);
9277
- if (hasDefaultImport && typeData.length === 1) {
9278
- const td = typeData[0];
9279
- imports.push(`import ${td.importName} from "${importFilePath}";`);
9280
- exports.push(`export { default as ${td.importName} } from "${importFilePath}";`);
9281
- } else if (hasDefaultImport) {
9282
- const defaultImport = typeData.find((td) => td.isDefault);
9283
- 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) => {
9284
9543
  if (td.originalName === "") return `${td.localName}`;
9285
9544
  else if (td.originalName === td.importName) return `${td.originalName}`;
9286
9545
  else return `${td.originalName} as ${td.importName}`;
9287
9546
  }).join(`, `);
9288
- imports.push(`import ${defaultImport.importName}, { ${namedPart} } from "${importFilePath}";`);
9289
- 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
+ });
9290
9558
  } else {
9291
9559
  const namedPart = typeData.sort(sortImportNames).map((td) => {
9292
9560
  if (td.originalName === "") return `${td.localName}`;
@@ -9309,8 +9577,8 @@ const generateComponentTypesFile = (config, buildCtx, areTypesInternal) => {
9309
9577
  c.push(` }`);
9310
9578
  c.push(`}`);
9311
9579
  c.push(`declare namespace LocalJSX {`);
9312
- if (modules.some((m) => m.requiredProps)) {
9313
- 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 };`);
9314
9582
  c.push(``);
9315
9583
  }
9316
9584
  c.push(...modules.map((m) => {
@@ -9327,7 +9595,7 @@ const generateComponentTypesFile = (config, buildCtx, areTypesInternal) => {
9327
9595
  c.push(...modules.map((m) => {
9328
9596
  if (m.explicitAttributes) {
9329
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] }`;
9330
- if (m.requiredProps && m.requiredProps.length > 0) {
9598
+ if (m.requiredProps && m.requiredProps.length > 0 && m.requiredProps.length <= MAX_ONE_OF_REQUIRED_PROPS) {
9331
9599
  const requiredUnions = m.requiredProps.map((prop) => {
9332
9600
  return `OneOf<"${prop.name}", ${m.tagNameAsPascal}["${prop.name}"], ${m.tagNameAsPascal}Attributes["${prop.name}"]>`;
9333
9601
  }).join(" & ");
@@ -9506,7 +9774,8 @@ const outputTypes = async (config, compilerCtx, buildCtx) => {
9506
9774
  * @returns a path to the build directory for that output target
9507
9775
  */
9508
9776
  const getAbsoluteBuildDir = (outputTarget) => {
9509
- return join$2("/", relative$1(outputTarget.dir, outputTarget.buildDir)) + "/";
9777
+ const relativeBuildDir = relative$1(outputTarget.dir, outputTarget.buildDir);
9778
+ return join$2("/", relativeBuildDir) + "/";
9510
9779
  };
9511
9780
  //#endregion
9512
9781
  //#region src/compiler/html/add-script-attr.ts
@@ -9526,7 +9795,8 @@ const addScriptDataAttribute = (config, doc, outputTarget) => {
9526
9795
  //#region src/compiler/html/inject-module-preloads.ts
9527
9796
  const optimizeCriticalPath = (doc, criticalBundlers, outputTarget) => {
9528
9797
  const buildDir = getAbsoluteBuildDir(outputTarget);
9529
- injectModulePreloads(doc, criticalBundlers.map((path) => join$2(buildDir, path)));
9798
+ const paths = criticalBundlers.map((path) => join$2(buildDir, path));
9799
+ injectModulePreloads(doc, paths);
9530
9800
  };
9531
9801
  const injectModulePreloads = (doc, paths) => {
9532
9802
  const existingLinks = Array.from(doc.querySelectorAll("link[rel=modulepreload]")).map((link) => link.getAttribute("href"));
@@ -9656,7 +9926,8 @@ const updateIndexHtmlServiceWorker = async (config, buildCtx, doc, outputTarget)
9656
9926
  else if (serviceWorker) await injectRegisterServiceWorker(buildCtx, outputTarget, doc);
9657
9927
  };
9658
9928
  const injectRegisterServiceWorker = async (buildCtx, outputTarget, doc) => {
9659
- const serviceWorker = getRegisterSwScript(doc, buildCtx, generateServiceWorkerUrl(outputTarget, outputTarget.serviceWorker));
9929
+ const swUrl = generateServiceWorkerUrl(outputTarget, outputTarget.serviceWorker);
9930
+ const serviceWorker = getRegisterSwScript(doc, buildCtx, swUrl);
9660
9931
  doc.body.appendChild(serviceWorker);
9661
9932
  };
9662
9933
  const injectUnregisterServiceWorker = (doc) => {
@@ -9826,7 +10097,7 @@ function readModulePaths(code) {
9826
10097
  function isImportOrExportDecl(stmt) {
9827
10098
  return ts.isExportDeclaration(stmt) || ts.isImportDeclaration(stmt);
9828
10099
  }
9829
- const MAX_JS_INLINE_SIZE = 1 * 1024;
10100
+ const MAX_JS_INLINE_SIZE = 1024;
9830
10101
  //#endregion
9831
10102
  //#region src/compiler/html/inline-style-sheets.ts
9832
10103
  const inlineStyleSheets = (compilerCtx, doc, maxSize, outputTarget) => {
@@ -9928,7 +10199,10 @@ const generateWww = async (config, compilerCtx, buildCtx, criticalPath, outputTa
9928
10199
  }
9929
10200
  if (!skipHtml) {
9930
10201
  if (buildCtx.indexDoc && outputTarget.indexHtml) await generateIndexHtml(config, compilerCtx, buildCtx, criticalPath, outputTarget, globalStylesMap);
9931
- 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
+ }
9932
10206
  }
9933
10207
  await generateHostConfig(compilerCtx, outputTarget);
9934
10208
  };
@@ -10013,24 +10287,26 @@ const generateIndexHtml = async (config, compilerCtx, buildCtx, criticalPath, ou
10013
10287
  */
10014
10288
  const generateHtmlFile = async (config, compilerCtx, buildCtx, doc, destPath, outputTarget, globalStylesMap) => {
10015
10289
  try {
10016
- 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);
10017
10292
  } catch (e) {
10018
10293
  catchError(buildCtx.diagnostics, e);
10019
10294
  }
10020
10295
  };
10021
- const MAX_CSS_INLINE_SIZE = 3 * 1024;
10296
+ const MAX_CSS_INLINE_SIZE = 3072;
10022
10297
  //#endregion
10023
10298
  //#region src/compiler/transformers/component-ssr/ssr-runtime-cmp-meta.ts
10024
10299
  const addHydrateRuntimeCmpMeta = (classMembers, cmp, buildCtx) => {
10025
10300
  const compactMeta = formatComponentRuntimeMeta(cmp, true);
10026
- const staticMember = createStaticGetter("cmpMeta", convertValueToLiteral({
10301
+ const cmpMeta = {
10027
10302
  $flags$: compactMeta[0],
10028
10303
  $tagName$: compactMeta[1],
10029
10304
  $members$: compactMeta[2],
10030
10305
  $listeners$: compactMeta[3],
10031
10306
  $lazyBundleId$: fakeBundleIds(cmp),
10032
10307
  $attrsToReflect$: getHydrateAttrsToReflect(cmp)
10033
- }));
10308
+ };
10309
+ const staticMember = createStaticGetter("cmpMeta", convertValueToLiteral(cmpMeta));
10034
10310
  addStaticStyleGetterWithinClass(classMembers, cmp, buildCtx);
10035
10311
  classMembers.push(staticMember);
10036
10312
  };
@@ -10156,7 +10432,7 @@ const getSsrBuildConditionals = (config, cmps) => {
10156
10432
  */
10157
10433
  const bundleSsrFactory = async (config, compilerCtx, buildCtx, appFactoryEntryCode) => {
10158
10434
  try {
10159
- return await bundleOutput(config, compilerCtx, buildCtx, {
10435
+ const bundleOpts = {
10160
10436
  id: "ssr",
10161
10437
  platform: "ssr",
10162
10438
  conditionals: getSsrBuildConditionals(config, buildCtx.components),
@@ -10164,7 +10440,8 @@ const bundleSsrFactory = async (config, compilerCtx, buildCtx, appFactoryEntryCo
10164
10440
  codeSplitting: false,
10165
10441
  inputs: { "@stencil/core/runtime/server/ssr-factory": "@stencil/core/runtime/server/ssr-factory" },
10166
10442
  loader: { "@stencil/core/runtime/server/ssr-factory": appFactoryEntryCode }
10167
- });
10443
+ };
10444
+ return await bundleOutput(config, compilerCtx, buildCtx, bundleOpts);
10168
10445
  } catch (e) {
10169
10446
  if (!buildCtx.hasError && isRolldownError(e)) loadRolldownDiagnostics(config, compilerCtx, buildCtx, e);
10170
10447
  }
@@ -10358,7 +10635,8 @@ const SSR_FACTORY_OUTRO = `
10358
10635
  * @returns The updated component metadata array.
10359
10636
  */
10360
10637
  const updateSsrComponents = async (cmps) => {
10361
- 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);
10362
10640
  };
10363
10641
  const updateSsrComponent = async (cmp) => {
10364
10642
  const cmpData = {
@@ -10478,7 +10756,8 @@ const writeSsrOutput = async (config, compilerCtx, buildCtx, outputTarget, rolld
10478
10756
  }));
10479
10757
  };
10480
10758
  const copySsrRunnerDts = async (config, compilerCtx, hydrateAppDirPath) => {
10481
- 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");
10482
10761
  const runnerDtsDestPath = join$2(hydrateAppDirPath, "index.d.ts");
10483
10762
  await compilerCtx.fs.copyFile(srcSsrDir, runnerDtsDestPath);
10484
10763
  };
@@ -10495,11 +10774,12 @@ const copySsrRunnerDts = async (config, compilerCtx, hydrateAppDirPath) => {
10495
10774
  */
10496
10775
  const buildSsrAppFor = async (format, rolldownBuild, config, compilerCtx, buildCtx, outputTargets) => {
10497
10776
  const file = format === "esm" ? "index.js" : "index.cjs";
10498
- await writeSsrOutputs(config, compilerCtx, buildCtx, outputTargets, await rolldownBuild.generate({
10777
+ const rolldownOutput = await rolldownBuild.generate({
10499
10778
  banner: generatePreamble(config),
10500
10779
  format,
10501
10780
  file
10502
- }));
10781
+ });
10782
+ await writeSsrOutputs(config, compilerCtx, buildCtx, outputTargets, rolldownOutput);
10503
10783
  };
10504
10784
  /**
10505
10785
  * Generate and build the SSR app and then write it to disk
@@ -10514,7 +10794,7 @@ const generateSsrApp = async (config, compilerCtx, buildCtx, outputTargets) => {
10514
10794
  const packageDir = join$2(config.sys.getCompilerExecutingPath(), "..", "..");
10515
10795
  const input = join$2(packageDir, "runtime", "server", "runner.mjs");
10516
10796
  const appData = join$2(packageDir, "runtime", "app-data", "index.js");
10517
- const rolldownAppBuild = await rolldown({
10797
+ const rolldownOptions = {
10518
10798
  ...config.rolldownConfig,
10519
10799
  external: ["node:stream"],
10520
10800
  input,
@@ -10549,7 +10829,8 @@ const generateSsrApp = async (config, compilerCtx, buildCtx, outputTargets) => {
10549
10829
  treeshake: false,
10550
10830
  onwarn: createOnWarnFn(buildCtx.diagnostics),
10551
10831
  checks: { pluginTimings: config.logLevel === "debug" }
10552
- });
10832
+ };
10833
+ const rolldownAppBuild = await rolldown(rolldownOptions);
10553
10834
  const buildPromises = [buildSsrAppFor("esm", rolldownAppBuild, config, compilerCtx, buildCtx, outputTargets)];
10554
10835
  if (outputTargets.some((o) => o.cjs)) buildPromises.push(buildSsrAppFor("cjs", rolldownAppBuild, config, compilerCtx, buildCtx, outputTargets));
10555
10836
  await Promise.all(buildPromises);
@@ -10559,7 +10840,8 @@ const generateSsrApp = async (config, compilerCtx, buildCtx, outputTargets) => {
10559
10840
  };
10560
10841
  const generateSsrFactory = async (config, compilerCtx, buildCtx) => {
10561
10842
  if (!buildCtx.hasError) try {
10562
- 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);
10563
10845
  if (rolldownFactoryBuild != null) {
10564
10846
  const rolldownOutput = await rolldownFactoryBuild.generate({
10565
10847
  format: "cjs",
@@ -10648,7 +10930,7 @@ const generateSsrWasmApp = async (config, compilerCtx, buildCtx, outputTargets)
10648
10930
  const packageDir = join$2(config.sys.getCompilerExecutingPath(), "..", "..");
10649
10931
  const input = join$2(packageDir, "runtime", "server", "runner.mjs");
10650
10932
  const appData = join$2(packageDir, "runtime", "app-data", "index.js");
10651
- const rolldownOutput = await (await rolldown({
10933
+ const rolldownOptions = {
10652
10934
  ...config.rolldownConfig,
10653
10935
  external: [],
10654
10936
  input,
@@ -10679,7 +10961,8 @@ const generateSsrWasmApp = async (config, compilerCtx, buildCtx, outputTargets)
10679
10961
  transform: { target: "es2020" },
10680
10962
  onwarn: createOnWarnFn(buildCtx.diagnostics),
10681
10963
  checks: { pluginTimings: config.logLevel === "debug" }
10682
- })).generate({
10964
+ };
10965
+ const rolldownOutput = await (await rolldown(rolldownOptions)).generate({
10683
10966
  banner: generatePreamble(config) + SSR_WASM_TIMER_POLYFILL,
10684
10967
  outro: SSR_WASM_OUTRO,
10685
10968
  format: "iife",
@@ -10912,7 +11195,8 @@ const createComponentMetadataProxy = (compilerMeta) => {
10912
11195
  * @returns the generated call expression
10913
11196
  */
10914
11197
  const createClassMetadataProxy = (compilerMeta, clazz) => {
10915
- const literalMeta = convertValueToLiteral(formatComponentRuntimeMeta(compilerMeta, true));
11198
+ const compactMeta = formatComponentRuntimeMeta(compilerMeta, true);
11199
+ const literalMeta = convertValueToLiteral(compactMeta);
10916
11200
  return ts.factory.createCallExpression(ts.factory.createIdentifier(PROXY_CUSTOM_ELEMENT), [], [clazz, literalMeta]);
10917
11201
  };
10918
11202
  //#endregion
@@ -10947,7 +11231,8 @@ const proxyCustomElement = (compilerCtx, transformOpts) => {
10947
11231
  for (const [stmtIndex, stmt] of tsSourceFile.statements.entries()) if (ts.isVariableStatement(stmt)) for (const [declarationIndex, declaration] of stmt.declarationList.declarations.entries()) {
10948
11232
  if (declaration.name.getText() !== principalComponent.componentClassName) continue;
10949
11233
  if (!ts.isClassExpression(declaration.initializer)) continue;
10950
- 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);
10951
11236
  ts.addSyntheticLeadingComment(proxyCreationCall, ts.SyntaxKind.MultiLineCommentTrivia, "@__PURE__", false);
10952
11237
  const proxiedComponentDeclaration = ts.factory.updateVariableDeclaration(declaration, declaration.name, declaration.exclamationToken, declaration.type, proxyCreationCall);
10953
11238
  const updatedDeclarationList = ts.factory.updateVariableDeclarationList(stmt.declarationList, [
@@ -11111,11 +11396,12 @@ function createStatesAddCall(memberName, stateName) {
11111
11396
  const updateNativeConstructor = (classMembers, moduleFile, cmp, classNode) => {
11112
11397
  if (cmp.isPlain) return;
11113
11398
  const cstrMethodArgs = [ts.factory.createParameterDeclaration(void 0, void 0, ts.factory.createIdentifier("registerHost"))];
11114
- updateConstructor(classNode, classMembers, [
11399
+ const nativeCstrStatements = [
11115
11400
  ...nativeInit(cmp),
11116
11401
  ...addCreateEvents(moduleFile, cmp),
11117
11402
  ...createNativeAttachInternalsBinding(cmp)
11118
- ], cstrMethodArgs, cmp.doesExtend);
11403
+ ];
11404
+ updateConstructor(classNode, classMembers, nativeCstrStatements, cstrMethodArgs, cmp.doesExtend);
11119
11405
  };
11120
11406
  /**
11121
11407
  * Generates a series of expression statements used to help initialize a Stencil component
@@ -11169,8 +11455,10 @@ const addNativeComponentMeta = (classMembers, cmp) => {
11169
11455
  //#endregion
11170
11456
  //#region src/compiler/transformers/component-native/native-static-style.ts
11171
11457
  const addNativeStaticStyle = (classMembers, cmp, buildCtx) => {
11172
- 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);
11173
- 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
+ }
11174
11462
  };
11175
11463
  const addMultipleModeStyleGetter = (classMembers, cmp, styles, buildCtx) => {
11176
11464
  const styleModes = [];
@@ -11309,7 +11597,8 @@ const updateNativeHostComponentHeritageClauses = (classNode, moduleFile) => {
11309
11597
  */
11310
11598
  const updateNativeBaseClass = (node, moduleFile) => {
11311
11599
  const withHeritageClauses = updateNativeHostComponentHeritageClauses(node, moduleFile);
11312
- const membersWithCtor = updateConstructor(withHeritageClauses, removeStaticMetaProperties(withHeritageClauses), [], void 0, false);
11600
+ const members = removeStaticMetaProperties(withHeritageClauses);
11601
+ const membersWithCtor = updateConstructor(withHeritageClauses, members, [], void 0, false);
11313
11602
  return ts.factory.updateClassDeclaration(withHeritageClauses, withHeritageClauses.modifiers, withHeritageClauses.name, withHeritageClauses.typeParameters, withHeritageClauses.heritageClauses, membersWithCtor);
11314
11603
  };
11315
11604
  /**
@@ -11417,9 +11706,11 @@ const generateLoaderModule = (components, outputTarget, relativeAssetPath) => {
11417
11706
  const autoStart = typeof autoLoaderConfig === "object" ? autoLoaderConfig.autoStart !== false : true;
11418
11707
  const tagsList = components.map((cmp) => `'${cmp.tagName}'`).join(", ");
11419
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` : "";
11420
11711
  return `
11421
11712
  import { transformTag, getRegistry } from '${STENCIL_INTERNAL_STANDALONE_CLIENT_PLATFORM_ID}';
11422
- ${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}
11423
11714
 
11424
11715
  /**
11425
11716
  * Tag names built at compile time.
@@ -11453,13 +11744,13 @@ let observer;
11453
11744
  /**
11454
11745
  * Scan a root element for undefined custom elements and load them.
11455
11746
  *
11456
- * Before any modules are imported we do two things to guarantee the documented
11457
- * Stencil lifecycle ordering (componentWillLoad top-down, componentDidLoad
11458
- * 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:
11459
11750
  *
11460
- * 1. Pre-mark every not-yet-upgraded Stencil element with empty \`s-p\`/\`s-rc\`
11461
- * arrays so the runtime's connectedCallback ancestor walk can always find a
11462
- * 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\`).
11463
11754
  *
11464
11755
  * 2. For every child Stencil element, push a Promise into its nearest Stencil
11465
11756
  * ancestor's \`s-p\` array. That Promise resolves only after the child's full
@@ -11468,6 +11759,15 @@ let observer;
11468
11759
  * descendants are ready - even when a descendant's module loads *after* the
11469
11760
  * ancestor has already started rendering.
11470
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
+ *
11471
11771
  * @param root - The root element to scan
11472
11772
  */
11473
11773
  async function load(root) {
@@ -11480,6 +11780,7 @@ async function load(root) {
11480
11780
  if (lookup[rootTag]) {
11481
11781
  if (!root['s-p']) root['s-p'] = [];
11482
11782
  if (!root['s-rc']) root['s-rc'] = [];
11783
+ if (!root['s-pc']) root['s-pc'] = [];
11483
11784
  if (!defined.has(rootTag)) pending.add(rootTag);
11484
11785
  elements.push(root);
11485
11786
  }
@@ -11491,6 +11792,7 @@ async function load(root) {
11491
11792
  if (lookup[tag]) {
11492
11793
  if (!el['s-p']) el['s-p'] = [];
11493
11794
  if (!el['s-rc']) el['s-rc'] = [];
11795
+ if (!el['s-pc']) el['s-pc'] = [];
11494
11796
  if (!defined.has(tag)) pending.add(tag);
11495
11797
  elements.push(el);
11496
11798
  }
@@ -11513,6 +11815,11 @@ async function load(root) {
11513
11815
  ancestor['s-p'].push(
11514
11816
  reg.whenDefined(tag).then(() => el['s-rp'])
11515
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
+ );
11516
11823
  break;
11517
11824
  }
11518
11825
  ancestor = ancestor.parentElement;
@@ -12045,11 +12352,12 @@ const getTypescriptPathFromUrl = (config, tsExecutingUrl, url) => {
12045
12352
  const tsBaseUrl = new URL("..", tsExecutingUrl).href;
12046
12353
  if (url.startsWith(tsBaseUrl)) {
12047
12354
  const tsFilePath = url.replace(tsBaseUrl, "/");
12048
- return normalizePath(config.sys.getLocalModulePath({
12355
+ const tsNodePath = config.sys.getLocalModulePath({
12049
12356
  rootDir: config.rootDir,
12050
12357
  moduleId: "@stencil/core",
12051
12358
  path: tsFilePath
12052
- }));
12359
+ });
12360
+ return normalizePath(tsNodePath);
12053
12361
  }
12054
12362
  return url;
12055
12363
  };
@@ -12092,9 +12400,25 @@ const tsResolveModuleNamePackageJsonPath = (config, compilerCtx, moduleName, con
12092
12400
  };
12093
12401
  //#endregion
12094
12402
  //#region src/compiler/transformers/static-to-meta/vdom.ts
12095
- 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) => {
12096
12419
  m.hasVdomRender = true;
12097
12420
  const hTag = args[0];
12421
+ const isSlotTag = ts.isStringLiteral(hTag) && hTag.text === "slot";
12098
12422
  if (!ts.isStringLiteral(hTag) && (!ts.isIdentifier(hTag) || hTag.text !== "Host")) m.hasVdomFunctional = true;
12099
12423
  if (args.length > 1) {
12100
12424
  const objectLiteral = args[1];
@@ -12107,32 +12431,46 @@ const gatherVdomMeta = (m, args) => {
12107
12431
  m.hasVdomRef = true;
12108
12432
  m.hasVdomStyle = true;
12109
12433
  m.hasVdomXlink = true;
12110
- } else if (ts.isObjectLiteralExpression(objectLiteral)) objectLiteral.properties.forEach((prop) => {
12111
- m.hasVdomAttribute = true;
12112
- if (ts.isSpreadAssignment(prop) || ts.isComputedPropertyName(prop.name)) {
12113
- m.hasVdomClass = true;
12114
- m.hasVdomKey = true;
12115
- m.hasVdomListener = true;
12116
- m.hasVdomPropOrAttr = true;
12117
- m.hasVdomRef = true;
12118
- m.hasVdomStyle = true;
12119
- m.hasVdomXlink = true;
12120
- } else if (prop.name && prop.name.text && prop.name.text.length > 0) {
12121
- const attrName = prop.name.text;
12122
- if (attrName === "key") m.hasVdomKey = true;
12123
- else if (attrName === "ref") m.hasVdomRef = true;
12124
- else if (attrName === "class" || attrName === "className") m.hasVdomClass = true;
12125
- else if (attrName === "style") m.hasVdomStyle = true;
12126
- else if (/^on(-|[A-Z])/.test(attrName)) m.hasVdomListener = true;
12127
- else if (attrName.startsWith("xlink")) {
12128
- 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;
12129
12443
  m.hasVdomPropOrAttr = true;
12130
- } else m.hasVdomPropOrAttr = true;
12131
- if (attrName === "part" && ts.isPropertyAssignment(prop) && ts.isStringLiteral(prop.initializer)) m.htmlParts.push(...prop.initializer.text.toLowerCase().split(" ").filter((part) => part.length > 0));
12132
- m.htmlAttrNames.push(attrName);
12133
- }
12134
- });
12135
- }
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("");
12136
12474
  if (!m.hasVdomText) for (let i = 2; i < args.length; i++) {
12137
12475
  const arg = args[i];
12138
12476
  if (!ts.isCallExpression(arg) || !ts.isIdentifier(arg.expression) || arg.expression.text !== "h") {
@@ -12170,10 +12508,10 @@ const visitCallExpressionArgs = (m, callExpressionName, args, typeChecker) => {
12170
12508
  const fnName = callExpressionName.escapedText;
12171
12509
  if (fnName === "h" || fnName === "__stencil_h" || fnName === "createElement") {
12172
12510
  visitCallExpressionArg(m, args[0], typeChecker);
12173
- if (fnName === "h" || fnName === "__stencil_h") gatherVdomMeta(m, args);
12511
+ if (fnName === "h" || fnName === "__stencil_h") gatherVdomMeta(m, args, typeChecker);
12174
12512
  } else if (fnName === "jsx" || fnName === "jsxs" || fnName === "_jsx" || fnName === "_jsxs") {
12175
12513
  visitCallExpressionArg(m, args[0], typeChecker);
12176
- gatherVdomMeta(m, args);
12514
+ gatherVdomMeta(m, args, typeChecker);
12177
12515
  if (args.length > 2 && args[2]) m.hasVdomKey = true;
12178
12516
  } else if (args.length > 1 && fnName === "createElementNS") visitCallExpressionArg(m, args[1], typeChecker);
12179
12517
  else if (fnName === "require" && args.length > 0 && m.originalImports) {
@@ -12229,7 +12567,8 @@ const resolveFunctionalComponentDep = (m, identifier, typeChecker) => {
12229
12567
  * @returns the updated typescript class declaration
12230
12568
  */
12231
12569
  const addComponentMetaStatic = (cmpNode, cmpMeta) => {
12232
- const cmpMetaStaticProp = createStaticGetter("COMPILER_META", convertValueToLiteral(getPublicCompilerMeta(cmpMeta)));
12570
+ const publicCompilerMeta = getPublicCompilerMeta(cmpMeta);
12571
+ const cmpMetaStaticProp = createStaticGetter("COMPILER_META", convertValueToLiteral(publicCompilerMeta));
12233
12572
  const classMembers = [...cmpNode.members, cmpMetaStaticProp];
12234
12573
  return ts.factory.updateClassDeclaration(cmpNode, retrieveModifierLike(cmpNode), cmpNode.name, cmpNode.typeParameters, cmpNode.heritageClauses, classMembers);
12235
12574
  };
@@ -12277,7 +12616,7 @@ const setComponentBuildConditionals = (cmpMeta) => {
12277
12616
  cmpMeta.hasStyle = true;
12278
12617
  cmpMeta.hasMode = cmpMeta.styles.some((s) => s.modeName !== "$");
12279
12618
  }
12280
- 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;
12281
12620
  cmpMeta.isPlain = !cmpMeta.hasMember && !cmpMeta.hasStyle && !cmpMeta.hasLifecycle && !cmpMeta.hasListener && !cmpMeta.hasVdomRender;
12282
12621
  if (cmpMeta.patches) {
12283
12622
  cmpMeta.hasPatchAll = !!cmpMeta.patches.all;
@@ -12405,7 +12744,8 @@ const getDecoratorParameter = (arg, typeChecker, diagnostics, errorNode) => {
12405
12744
  */
12406
12745
  const resolveVariableValue = (node, typeChecker, diagnostics, errorNode) => {
12407
12746
  if (ts.isIdentifier(node)) {
12408
- const symbol = typeChecker.getSymbolAtLocation(node);
12747
+ let symbol = typeChecker.getSymbolAtLocation(node);
12748
+ if (symbol && symbol.flags & ts.SymbolFlags.Alias) symbol = typeChecker.getAliasedSymbol(symbol);
12409
12749
  if (!symbol || !symbol.valueDeclaration) {
12410
12750
  const err = buildError(diagnostics);
12411
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.`;
@@ -12605,8 +12945,10 @@ function parseCustomStatesFromDecorator(decorator, typeChecker) {
12605
12945
  //#region src/compiler/transformers/decorators-to-static/style-to-static.ts
12606
12946
  const styleToStatic = (newMembers, componentOptions) => {
12607
12947
  const defaultModeStyles = [];
12608
- if (componentOptions.styleUrls) if (Array.isArray(componentOptions.styleUrls)) defaultModeStyles.push(...normalizeStyleUrl(componentOptions.styleUrls));
12609
- 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
+ }
12610
12952
  if (componentOptions.styleUrl) defaultModeStyles.push(...normalizeStyleUrl(componentOptions.styleUrl));
12611
12953
  let styleUrls = {};
12612
12954
  if (componentOptions.styleUrls && !Array.isArray(componentOptions.styleUrls)) styleUrls = normalizeStyleUrls(componentOptions.styleUrls);
@@ -12614,7 +12956,8 @@ const styleToStatic = (newMembers, componentOptions) => {
12614
12956
  if (Object.keys(styleUrls).length > 0) {
12615
12957
  const originalStyleUrls = convertValueToLiteral(styleUrls);
12616
12958
  newMembers.push(createStaticGetter("originalStyleUrls", originalStyleUrls));
12617
- const normalizedStyleExp = convertValueToLiteral(normalizeExtension(styleUrls));
12959
+ const norlizedStyleExt = normalizeExtension(styleUrls);
12960
+ const normalizedStyleExp = convertValueToLiteral(norlizedStyleExt);
12618
12961
  newMembers.push(createStaticGetter("styleUrls", normalizedStyleExp));
12619
12962
  }
12620
12963
  if (componentOptions.globalStyleUrl) newMembers.push(createStaticGetter("originalGlobalStyleUrl", convertValueToLiteral(componentOptions.globalStyleUrl)));
@@ -12643,7 +12986,10 @@ const normalizeExtension = (styleUrls) => {
12643
12986
  return compilerStyleUrls;
12644
12987
  };
12645
12988
  const useCss = (stylePath) => {
12646
- 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");
12647
12993
  };
12648
12994
  const normalizeStyleUrls = (styleUrls) => {
12649
12995
  const compilerStyleUrls = {};
@@ -12793,6 +13139,13 @@ const validateComponent = (config, diagnostics, typeChecker, componentOptions, c
12793
13139
  }
12794
13140
  }
12795
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
+ }
12796
13149
  const constructor = cmpNode.members.find(ts.isConstructorDeclaration);
12797
13150
  if (constructor && constructor.parameters.length > 0) {
12798
13151
  const err = buildError(diagnostics);
@@ -12830,7 +13183,8 @@ const validateComponent = (config, diagnostics, typeChecker, componentOptions, c
12830
13183
  err.messageText = `To allow efficient bundling, modules using @Component() can only have a single export which is the component class itself.
12831
13184
  Any other exports should be moved to a separate file.
12832
13185
  For further information check out: https://stenciljs.com/docs/module-bundling`;
12833
- augmentDiagnosticWithNode(err, symbol.valueDeclaration ? symbol.valueDeclaration : symbol.declarations[0]);
13186
+ const errorNode = symbol.valueDeclaration ? symbol.valueDeclaration : symbol.declarations[0];
13187
+ augmentDiagnosticWithNode(err, errorNode);
12834
13188
  });
12835
13189
  if (nonTypeExports.length > 0) return false;
12836
13190
  }
@@ -13007,7 +13361,7 @@ const validateEventName = (config, diagnostics, node, eventName) => {
13007
13361
  augmentDiagnosticWithNode(warn, node);
13008
13362
  return;
13009
13363
  }
13010
- if (!config.suppressReservedEventNameWarnings && DOM_EVENT_NAMES.has(eventName.toLowerCase())) {
13364
+ if (!config.compat?.suppressEventNameWarnings && DOM_EVENT_NAMES.has(eventName.toLowerCase())) {
13011
13365
  const diagnostic = buildWarn(diagnostics);
13012
13366
  diagnostic.messageText = `The event name conflicts with the "${eventName}" native DOM event name.`;
13013
13367
  augmentDiagnosticWithNode(diagnostic, node);
@@ -13306,7 +13660,8 @@ var ImportAliasMap = class extends Map {
13306
13660
  //#endregion
13307
13661
  //#region src/compiler/transformers/decorators-to-static/listen-decorator.ts
13308
13662
  const listenDecoratorsToStatic = (diagnostics, typeChecker, decoratedMembers, newMembers, decoratorName) => {
13309
- 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);
13310
13665
  if (flatListeners.length > 0) newMembers.push(createStaticGetter("listeners", convertValueToLiteral(flatListeners)));
13311
13666
  };
13312
13667
  const parseListenDecorators = (diagnostics, typeChecker, method, decoratorName) => {
@@ -13340,7 +13695,7 @@ const parseListener = (eventName, opts = {}, methodName) => {
13340
13695
  passive: typeof opts.passive === "boolean" ? opts.passive : PASSIVE_TRUE_DEFAULTS.has(rawEventName.toLowerCase())
13341
13696
  };
13342
13697
  };
13343
- const PASSIVE_TRUE_DEFAULTS = new Set([
13698
+ const PASSIVE_TRUE_DEFAULTS = /* @__PURE__ */ new Set([
13344
13699
  "dragstart",
13345
13700
  "drag",
13346
13701
  "dragend",
@@ -13389,7 +13744,7 @@ const PASSIVE_TRUE_DEFAULTS = new Set([
13389
13744
  * @param node the TypeScript AST node at which the class member is defined
13390
13745
  */
13391
13746
  const validatePublicName = (config, diagnostics, memberName, decorator, memberType, node) => {
13392
- if (config.suppressReservedPublicNameWarnings) return;
13747
+ if (config.compat?.suppressPublicNameWarnings) return;
13393
13748
  if (RESERVED_PUBLIC_MEMBERS.has(memberName.toLowerCase())) {
13394
13749
  const warn = buildWarn(diagnostics);
13395
13750
  warn.messageText = [
@@ -13800,7 +14155,8 @@ const parsePropDecorator = (config, diagnostics, typeChecker, program, prop, dec
13800
14155
  const returnExpression = (prop.body?.statements.find((st) => ts.isReturnStatement(st))).expression;
13801
14156
  if (returnExpression && ts.isLiteralExpression(returnExpression)) propMeta.defaultValue = returnExpression.getText();
13802
14157
  else if (returnExpression && ts.isPropertyAccessExpression(returnExpression)) {
13803
- const foundProp = findGetProp(returnExpression.name.getText(), newMembers);
14158
+ const nameToFind = returnExpression.name.getText();
14159
+ const foundProp = findGetProp(nameToFind, newMembers);
13804
14160
  if (foundProp && foundProp.initializer) {
13805
14161
  propMeta.defaultValue = resolveInitializerText(foundProp.initializer, typeChecker);
13806
14162
  if (propMeta.type === "unknown") {
@@ -14088,8 +14444,10 @@ const serializeDecoratorsToStatic = (typeChecker, decoratedProps, newMembers, de
14088
14444
  return [];
14089
14445
  });
14090
14446
  const serializers = decoratedProps.filter(ts.isMethodDeclaration).flatMap((method) => parseSerializeDecorator(typeChecker, method, decoratorName, props));
14091
- if (serializers.length > 0) if (translateType === "PropSerialize") newMembers.push(createStaticGetter("serializers", convertValueToLiteral(serializers)));
14092
- 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
+ }
14093
14451
  return serializers;
14094
14452
  };
14095
14453
  const parseSerializeDecorator = (typeChecker, method, decoratorName, props) => {
@@ -14145,7 +14503,8 @@ const stateDecoratorToStatic = (prop, typeChecker, decoratorName) => {
14145
14503
  //#endregion
14146
14504
  //#region src/compiler/transformers/decorators-to-static/watch-decorator.ts
14147
14505
  const watchDecoratorsToStatic = (typeChecker, decoratedProps, newMembers, decoratorName) => {
14148
- 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);
14149
14508
  if (flatWatchers.length > 0) newMembers.push(createStaticGetter("watchers", convertValueToLiteral(flatWatchers)));
14150
14509
  };
14151
14510
  const parseWatchDecorator = (typeChecker, method, decoratorName) => {
@@ -14266,19 +14625,21 @@ const removeStencilMethodDecorators = (classMembers, diagnostics, importAliasMap
14266
14625
  return classMembers.map((member) => {
14267
14626
  const currentDecorators = retrieveTsDecorators(member);
14268
14627
  const newDecorators = filterDecorators(currentDecorators, MEMBER_DECORATORS_TO_REMOVE.map((decorator) => importAliasMap.get(decorator)));
14269
- 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);
14270
- else if (ts.isGetAccessor(member)) return ts.factory.updateGetAccessorDeclaration(member, [...newDecorators ?? [], ...retrieveTsModifiers(member) ?? []], member.name, member.parameters, member.type, member.body);
14271
- else if (ts.isSetAccessor(member)) {
14272
- const err = buildError(diagnostics);
14273
- err.messageText = "A get accessor should be decorated before a set accessor";
14274
- augmentDiagnosticWithNode(err, member);
14275
- } else if (ts.isPropertyDeclaration(member)) {
14276
- const modifiers = retrieveTsModifiers(member);
14277
- return ts.factory.updatePropertyDeclaration(member, [...newDecorators ?? [], ...modifiers ?? []], member.name, member.questionToken, member.type, member.initializer);
14278
- } else {
14279
- const err = buildError(diagnostics);
14280
- err.messageText = "Unknown class member encountered!";
14281
- 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
+ }
14282
14643
  }
14283
14644
  return member;
14284
14645
  });
@@ -14423,15 +14784,80 @@ const parseStaticWatchers = (staticMembers) => {
14423
14784
  });
14424
14785
  };
14425
14786
  //#endregion
14426
- //#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
+ }
14834
+ /**
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
+ }
14427
14853
  /**
14428
- * Given two arrays of static members, return a new array containing only the
14429
- * members from the first array that are not present in the second array.
14430
- * This is used to de-dupe static members that are inherited from a parent class.
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.
14431
14857
  *
14432
- * @param dedupeMembers the array of static members to de-dupe
14433
- * @param staticMembers the array of static members to compare against
14434
- * @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
14435
14861
  */
14436
14862
  const deDupeMembers = (dedupeMembers, staticMembers) => {
14437
14863
  return dedupeMembers.filter((s) => !staticMembers.some((d) => {
@@ -14439,22 +14865,62 @@ const deDupeMembers = (dedupeMembers, staticMembers) => {
14439
14865
  return d.name === s.name;
14440
14866
  }));
14441
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
14442
14915
  /**
14443
- * When a parent-class source file is fetched directly from disk (via
14444
- * {@link tsGetSourceFile}) rather than from the compiler's moduleMap cache, it
14445
- * arrives with its original decorator syntax intact. The static-meta parsers
14446
- * (`parseStaticProps`, `parseStaticStates`, etc.) only understand the static-
14447
- * getter form produced by {@link convertDecoratorsToStatic}.
14448
- *
14449
- * This helper creates a self-contained mini TypeScript program for the single
14450
- * file and runs the decorator→static transformer on it, returning the
14451
- * transformed source file. Prop types may be under-resolved (external imports
14452
- * are not available in the mini program) and will fall back to `any`, which is
14453
- * acceptable for the purpose of walking the inheritance chain.
14454
- *
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.
14455
14921
  * @param sourceFile the raw (decorator-syntax) source file from disk
14456
14922
  * @param config the current Stencil validated config
14457
- * @param target the script target to use when converting decorators to static (if needed)
14923
+ * @param target the script target to convert decorators with
14458
14924
  * @returns the source file with decorators converted to static getters
14459
14925
  */
14460
14926
  function convertDiskSourceFileDecorators(sourceFile, config, target = ts.ScriptTarget.ESNext) {
@@ -14475,26 +14941,24 @@ function convertDiskSourceFileDecorators(sourceFile, config, target = ts.ScriptT
14475
14941
  return ts.createSourceFile(sourceFile.fileName, printed, target, true);
14476
14942
  }
14477
14943
  /**
14478
- * Helper function to resolve and process an extended class from a module.
14479
- * This handles:
14480
- * 1. Resolving the module path
14481
- * 2. Getting the source file
14482
- * 3. Finding the class declaration
14483
- * 4. Adding to dependent classes tree
14484
- *
14485
- * @param compilerCtx - the current compiler context
14486
- * @param buildCtx - the current build context
14487
- * @param classDeclaration - the current class being analyzed
14488
- * @param currentSource - the source file of the current class
14489
- * @param moduleSpecifier - the module path to resolve
14490
- * @param className - the name of the class to find in the resolved module
14491
- * @param dependentClasses - the array to add found classes to
14492
- * @param typeChecker - the TypeScript type checker
14493
- * @param ogModule - the original module file of the class declaration
14494
- * @param targetScriptTarget - the script target to use when converting decorators to static (if needed)
14495
- * @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`
14496
14960
  */
14497
- 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) {
14498
14962
  let keepLooking = true;
14499
14963
  const foundFile = tsResolveModuleName(buildCtx.config, compilerCtx, moduleSpecifier, currentSource.fileName);
14500
14964
  if (!foundFile?.resolvedModule || !className) return;
@@ -14503,7 +14967,7 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
14503
14967
  foundSource = tsGetSourceFile(buildCtx.config, foundFile);
14504
14968
  if (!foundSource) {
14505
14969
  const err = buildWarn(buildCtx.diagnostics);
14506
- err.messageText = `Unable to resolve import "${moduleSpecifier}" from "${currentSource.fileName}".
14970
+ err.messageText = `Unable to resolve import "${moduleSpecifier}" from "${currentSource.fileName}".
14507
14971
  This can happen when trying to resolve .js files and "allowJs" is not set to "true" in your tsconfig.json.`;
14508
14972
  if (!buildCtx.config._isTesting) augmentDiagnosticWithNode(err, classDeclaration);
14509
14973
  return;
@@ -14512,8 +14976,10 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
14512
14976
  }
14513
14977
  const matchedStatement = foundSource.statements.find(matchesNamedDeclaration(className));
14514
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);
14515
14981
  const err = buildWarn(buildCtx.diagnostics);
14516
- err.messageText = `Unable to find "${className}" in the imported module "${moduleSpecifier}".
14982
+ err.messageText = `Unable to find "${className}" in the imported module "${moduleSpecifier}".
14517
14983
  Please import class / mixin-factory declarations directly and not via barrel files.`;
14518
14984
  if (!buildCtx.config._isTesting) augmentDiagnosticWithNode(err, classDeclaration);
14519
14985
  return;
@@ -14533,71 +14999,20 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
14533
14999
  }
14534
15000
  return foundClassDeclaration;
14535
15001
  }
14536
- /**
14537
- * A recursive function that walks the AST to find a class declaration.
14538
- * @param node the current AST node
14539
- * @param depth the current depth in the AST
14540
- * @param name optional name of the class to find
14541
- * @returns the found class declaration or undefined
14542
- */
14543
- function findClassWalk(node, name, depth = 0) {
14544
- if (!node) return void 0;
14545
- if (node && ts.isClassDeclaration(node)) {
14546
- if (!name || node.name?.text === name) return node;
14547
- } else if (node && ts.isVariableDeclaration(node) && (!name || name === (node.name?.text || node.name?.escapedText)) && node.initializer && ts.isArrowFunction(node.initializer)) {
14548
- let found;
14549
- ts.forEachChild(node.initializer.body, (child) => {
14550
- if (found) return;
14551
- if (ts.isClassDeclaration(child)) found = child;
14552
- });
14553
- return found;
14554
- }
14555
- let found;
14556
- ts.forEachChild(node, (child) => {
14557
- if (found) return;
14558
- const result = findClassWalk(child, name, depth + 1);
14559
- if (result) found = result;
14560
- });
14561
- return found;
14562
- }
14563
- /**
14564
- * A function that checks if a statement matches a named declaration.
14565
- * @param name the name to match
14566
- * @returns a function that checks if a statement is a named declaration
14567
- */
14568
- function matchesNamedDeclaration(name) {
14569
- return function(stmt) {
14570
- if (ts.isClassDeclaration(stmt) && stmt.name?.text === name) return true;
14571
- if (ts.isFunctionDeclaration(stmt) && stmt.name?.text === name) return true;
14572
- if (ts.isVariableStatement(stmt)) {
14573
- for (const decl of stmt.declarationList.declarations) if (ts.isIdentifier(decl.name) && decl.name.text === name) return true;
14574
- }
14575
- return false;
14576
- };
14577
- }
14578
- /**
14579
- * Helper function to convert a .d.ts declaration file path to its corresponding
14580
- * .js source file path and get the source file from the compiler context.
14581
- * This is needed because in external projects the extended class may only be found as a .d.ts declaration.
14582
- * *
14583
- * @param declarationSourceFile the path to the .d.ts declaration file
14584
- * @param compilerCtx the current compiler context
14585
- * @returns the corresponding .js source file
14586
- */
14587
15002
  function convertDtsToJs(declarationSourceFile, compilerCtx) {
14588
15003
  const jsPath = normalizePath(declarationSourceFile.replace(/\.d\.ts$/, ".js").replace("/types/", "/collection/"));
14589
15004
  return compilerCtx.moduleMap.get(jsPath)?.staticSourceFile;
14590
15005
  }
14591
15006
  /**
14592
- * A recursive function that builds a tree of classes that extend from each other.
14593
- *
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).
14594
15009
  * @param compilerCtx the current compiler context
14595
15010
  * @param classDeclaration a class declaration to analyze
14596
- * @param dependentClasses a flat array tree of classes that extend from each other
15011
+ * @param dependentClasses the flat array to accumulate found classes into
14597
15012
  * @param typeChecker the TypeScript type checker
14598
15013
  * @param buildCtx the current build context
14599
15014
  * @param ogModule the original module file of the class declaration
14600
- * @returns a flat array of classes that extend from each other, including the current class
15015
+ * @returns `dependentClasses`, mutated in place
14601
15016
  */
14602
15017
  function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeChecker, buildCtx, ogModule) {
14603
15018
  const hasHeritageClauses = classDeclaration.heritageClauses;
@@ -14614,10 +15029,10 @@ function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeC
14614
15029
  });
14615
15030
  classIdentifiers.forEach((extendee) => {
14616
15031
  try {
14617
- const symbol = typeChecker?.getSymbolAtLocation(extendee);
14618
- const aliasedSymbol = symbol ? typeChecker.getAliasedSymbol(symbol) : void 0;
14619
- let source = aliasedSymbol?.declarations?.[0].getSourceFile();
14620
- 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;
14621
15036
  if (source.fileName.endsWith(".d.ts")) {
14622
15037
  source = convertDtsToJs(source.fileName, compilerCtx);
14623
15038
  declarations = [...source.statements];
@@ -14689,7 +15104,8 @@ function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeC
14689
15104
  if (statement.importClause?.namedBindings && ts.isNamedImports(statement.importClause?.namedBindings)) statement.importClause?.namedBindings.elements.forEach((element) => {
14690
15105
  if (element.name.getText() === extendee.getText()) {
14691
15106
  const className = element.propertyName?.getText() || element.name.getText();
14692
- 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);
14693
15109
  }
14694
15110
  });
14695
15111
  });
@@ -14698,17 +15114,15 @@ function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeC
14698
15114
  return dependentClasses;
14699
15115
  }
14700
15116
  /**
14701
- * Given a class declaration, this function will analyze its heritage clauses
14702
- * to find any extended classes, and then parse the static members of those
14703
- * extended classes to merge them into the current class's metadata.
14704
- *
14705
- * @param compilerCtx - the current compiler context
14706
- * @param typeChecker - the TypeScript type checker
14707
- * @param buildCtx - the current build context
14708
- * @param cmpNode - the extending class declaration
14709
- * @param staticMembers - the static members of the extending class to merge with the extended class members
14710
- * @param moduleFile - the module file of the extending class
14711
- * @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
14712
15126
  */
14713
15127
  function mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, staticMembers, moduleFile) {
14714
15128
  const tree = buildExtendsTree(compilerCtx, cmpNode, [], typeChecker, buildCtx, moduleFile);
@@ -14725,10 +15139,10 @@ function mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, sta
14725
15139
  let deserializers = parseStaticSerializers(staticMembers, "deserializers");
14726
15140
  tree.forEach((extendedClass) => {
14727
15141
  const extendedStaticMembers = extendedClass.classNode.members.filter(isStaticGetter);
14728
- const mixinProps = parseStaticProps(extendedStaticMembers) ?? [];
15142
+ const mixinProps = reanchorInheritedTypeReferences(parseStaticProps(extendedStaticMembers) ?? [], extendedClass.fileName, moduleFile.sourceFilePath);
14729
15143
  const mixinStates = parseStaticStates(extendedStaticMembers) ?? [];
14730
- const mixinMethods = parseStaticMethods(extendedStaticMembers) ?? [];
14731
- const mixinEvents = parseStaticEvents(extendedStaticMembers) ?? [];
15144
+ const mixinMethods = reanchorInheritedTypeReferences(parseStaticMethods(extendedStaticMembers) ?? [], extendedClass.fileName, moduleFile.sourceFilePath);
15145
+ const mixinEvents = reanchorInheritedTypeReferences(parseStaticEvents(extendedStaticMembers) ?? [], extendedClass.fileName, moduleFile.sourceFilePath);
14732
15146
  const isMixin = mixinProps.length > 0 || mixinStates.length > 0 || mixinMethods.length > 0 || mixinEvents.length > 0;
14733
15147
  const module = compilerCtx.moduleMap.get(extendedClass.fileName);
14734
15148
  if (module) {
@@ -14770,6 +15184,8 @@ function mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, sta
14770
15184
  deserializers
14771
15185
  };
14772
15186
  }
15187
+ //#endregion
15188
+ //#region src/compiler/transformers/static-to-meta/class-extension/extract-inherited-meta.ts
14773
15189
  const EMPTY_DOCS = {
14774
15190
  text: "",
14775
15191
  tags: []
@@ -14805,19 +15221,14 @@ function extractDecoratorOptions(node) {
14805
15221
  return result;
14806
15222
  }
14807
15223
  /**
14808
- * Extract Stencil member metadata from source text using parse-only TypeScript
14809
- * (no Program, no TypeChecker). Handles both decorator syntax (.tsx source files)
14810
- * and compiled static getter syntax (.js collection files).
14811
- *
14812
- * @param code source text to parse
14813
- * @param className name of the class to extract metadata from
14814
- * @param fileName virtual filename used to determine script kind
14815
- * @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
14816
15230
  */
14817
- function extractInheritedMeta(code, className, fileName = "__stencil_parent__.tsx") {
14818
- const scriptKind = fileName.endsWith(".tsx") || fileName.endsWith(".ts") ? ts.ScriptKind.TSX : ts.ScriptKind.JS;
14819
- const classDecl = ts.createSourceFile(fileName, code, ts.ScriptTarget.ESNext, true, scriptKind).statements.filter(ts.isClassDeclaration).find((c) => c.name?.text === className);
14820
- if (!classDecl) return null;
15231
+ function extractInheritedMetaFromClass(classDecl) {
14821
15232
  const methodNames = classDecl.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean);
14822
15233
  const staticMembers = classDecl.members.filter(isStaticGetter);
14823
15234
  if (staticMembers.some((m) => ts.isGetAccessorDeclaration(m) && ts.isIdentifier(m.name) && [
@@ -14917,11 +15328,68 @@ function extractInheritedMeta(code, className, fileName = "__stencil_parent__.ts
14917
15328
  methodNames
14918
15329
  };
14919
15330
  }
14920
- 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) {
14921
15387
  const heritage = node.heritageClauses?.find((h) => h.token === ts.SyntaxKind.ExtendsKeyword);
14922
- if (!heritage?.types.length) return null;
15388
+ if (!heritage?.types.length) return [];
14923
15389
  const expr = heritage.types[0].expression;
14924
- 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 [];
14925
15393
  }
14926
15394
  function findImportSpecifier(sf, localName) {
14927
15395
  for (const stmt of sf.statements) {
@@ -14937,17 +15405,208 @@ function findImportSpecifier(sf, localName) {
14937
15405
  return null;
14938
15406
  }
14939
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
+ /**
14940
15593
  * Resolves the inheritance chain for a component using a caller-supplied
14941
- * `resolveImport` callback instead of the full compiler infrastructure.
14942
- * 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, ...)`).
14943
15598
  *
14944
15599
  * @param cmpNode the component's class declaration
14945
15600
  * @param staticMembers static getter members already parsed from the component
14946
15601
  * @param sourceFile the source file containing the component (for import resolution)
14947
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
14948
15607
  * @returns merged metadata including all inherited members
14949
15608
  */
14950
- function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceFile, resolveImport) {
15609
+ function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceFile, resolveImport, config, buildCtx) {
14951
15610
  let doesExtend = false;
14952
15611
  let properties = parseStaticProps(staticMembers);
14953
15612
  let states = parseStaticStates(staticMembers);
@@ -14958,42 +15617,10 @@ function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceF
14958
15617
  let classMethods = cmpNode.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean);
14959
15618
  const serializers = [];
14960
15619
  const deserializers = [];
14961
- let currentNode = cmpNode;
14962
- let currentSf = sourceFile;
14963
- let currentPath = sourceFile.fileName;
14964
- const visited = /* @__PURE__ */ new Set();
14965
- while (true) {
14966
- const parentClassName = getExtendsClassName(currentNode);
14967
- if (!parentClassName) break;
14968
- const specifier = findImportSpecifier(currentSf, parentClassName);
14969
- if (!specifier) break;
14970
- const resolved = resolveImport(specifier, currentPath);
14971
- if (!resolved) break;
14972
- const { code, path: resolvedPath } = resolved;
14973
- if (visited.has(resolvedPath)) break;
14974
- visited.add(resolvedPath);
14975
- const isTs = resolvedPath.endsWith(".tsx") || resolvedPath.endsWith(".ts");
14976
- const parentSf = ts.createSourceFile(resolvedPath, code, ts.ScriptTarget.ESNext, true, isTs ? ts.ScriptKind.TSX : ts.ScriptKind.JS);
14977
- const parentClass = parentSf.statements.filter(ts.isClassDeclaration).find((c) => c.name?.text === parentClassName);
14978
- if (!parentClass) break;
14979
- const parentStaticMembers = parentClass.members.filter(isStaticGetter);
14980
- const parentMeta = parentStaticMembers.some((m) => ts.isGetAccessorDeclaration(m) && ts.isIdentifier(m.name) && [
14981
- "properties",
14982
- "states",
14983
- "events",
14984
- "listeners",
14985
- "watchers",
14986
- "methods"
14987
- ].includes(m.name.text)) ? {
14988
- properties: parseStaticProps(parentStaticMembers),
14989
- states: parseStaticStates(parentStaticMembers),
14990
- methods: parseStaticMethods(parentStaticMembers),
14991
- events: parseStaticEvents(parentStaticMembers),
14992
- listeners: parseStaticListeners(parentStaticMembers),
14993
- watchers: parseStaticWatchers(parentStaticMembers),
14994
- methodNames: parentClass.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean)
14995
- } : extractInheritedMeta(code, parentClassName, resolvedPath);
14996
- 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);
14997
15624
  doesExtend = true;
14998
15625
  const mixinPropsExcludingStates = parentMeta.properties.filter((mp) => !states.some((s) => s.name === mp.name));
14999
15626
  const mixinStatesExcludingProps = parentMeta.states.filter((ms) => !properties.some((p) => p.name === ms.name));
@@ -15004,10 +15631,7 @@ function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceF
15004
15631
  listeners = [...deDupeMembers(parentMeta.listeners, listeners), ...listeners];
15005
15632
  watchers = [...deDupeMembers(parentMeta.watchers, watchers), ...watchers];
15006
15633
  classMethods = [...classMethods, ...parentMeta.methodNames];
15007
- currentNode = parentClass;
15008
- currentSf = parentSf;
15009
- currentPath = resolvedPath;
15010
- }
15634
+ });
15011
15635
  return {
15012
15636
  doesExtend,
15013
15637
  properties,
@@ -15125,9 +15749,7 @@ const parseStaticPatches = (encapsulation, staticMembers) => {
15125
15749
  case "clone":
15126
15750
  result.clone = true;
15127
15751
  break;
15128
- case "insert":
15129
- result.insert = true;
15130
- break;
15752
+ case "insert": result.insert = true;
15131
15753
  }
15132
15754
  return Object.keys(result).length > 0 ? result : null;
15133
15755
  };
@@ -15291,8 +15913,9 @@ const parseStaticComponentMeta = (compilerCtx, typeChecker, cmpNode, moduleFile,
15291
15913
  const staticMembers = cmpNode.members.filter(isStaticGetter);
15292
15914
  const tagName = getComponentTagName(staticMembers);
15293
15915
  if (tagName == null) return cmpNode;
15294
- 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);
15295
- 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);
15296
15919
  const isCollectionDependency = moduleFile.isCollectionDependency;
15297
15920
  const encapsulation = parseStaticEncapsulation(staticMembers);
15298
15921
  const cmp = {
@@ -15380,6 +16003,7 @@ const parseStaticComponentMeta = (compilerCtx, typeChecker, cmpNode, moduleFile,
15380
16003
  htmlAttrNames: [],
15381
16004
  htmlTagNames: [],
15382
16005
  htmlParts: [],
16006
+ htmlSlots: [],
15383
16007
  isUpdateable: false,
15384
16008
  potentialCmpRefs: [],
15385
16009
  dependents: [],
@@ -15402,9 +16026,11 @@ const parseStaticComponentMeta = (compilerCtx, typeChecker, cmpNode, moduleFile,
15402
16026
  cmp.hasModernPropertyDecls = detectModernPropDeclarations(cmpNode) || doesExtend;
15403
16027
  cmp.htmlAttrNames = unique(cmp.htmlAttrNames);
15404
16028
  cmp.htmlTagNames = unique(cmp.htmlTagNames);
16029
+ cmp.htmlSlots = unique(cmp.htmlSlots);
15405
16030
  cmp.hasSlot = cmp.hasSlot || cmp.htmlTagNames.includes("slot");
15406
16031
  cmp.potentialCmpRefs = unique(cmp.potentialCmpRefs);
15407
16032
  setComponentBuildConditionals(cmp);
16033
+ if (cmp.isPlain && cmpNode.heritageClauses?.some((c) => c.token === ts.SyntaxKind.ExtendsKeyword)) cmp.isPlain = false;
15408
16034
  if (transformOpts && transformOpts.componentMetadata === "compilerstatic") cmpNode = addComponentMetaStatic(cmpNode, cmp);
15409
16035
  const foundIndex = moduleFile.cmps.findIndex((c) => c.tagName === cmp.tagName && c.sourceFilePath === cmp.sourceFilePath);
15410
16036
  if (foundIndex > -1) moduleFile.cmps[foundIndex] = cmp;
@@ -15412,22 +16038,32 @@ const parseStaticComponentMeta = (compilerCtx, typeChecker, cmpNode, moduleFile,
15412
16038
  compilerCtx.nodeMap.set(cmpNode, cmp);
15413
16039
  return cmpNode;
15414
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
+ };
15415
16051
  const validateComponentMembers = (node, buildCtx) => {
15416
16052
  /**
15417
16053
  * validate if:
15418
16054
  */
15419
- 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)) {
15420
16056
  const propName = node.name.escapedText;
15421
- const decorator = ts.getDecorators(node.parent)[0];
15422
- /**
15423
- * the class is actually a Stencil component, has a decorator with a property named "tag"
15424
- */
15425
- 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")) {
15426
- const componentName = node.parent.name.getText();
15427
- const err = buildWarn(buildCtx.diagnostics);
15428
- 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.`;
15429
- augmentDiagnosticWithNode(err, node);
15430
- }
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);
15431
16067
  }
15432
16068
  };
15433
16069
  const parseVirtualProps = (docs) => {
@@ -15470,7 +16106,7 @@ const parseModuleImport = (config, compilerCtx, buildCtx, moduleFile, dirPath, i
15470
16106
  importPath = normalizePath(importPath);
15471
16107
  moduleFile.localImports.push(importPath);
15472
16108
  } else if (importPath.startsWith(".")) {
15473
- importPath = normalizePath(resolve$2(dirPath, importPath));
16109
+ importPath = normalizePath(join$2(dirPath, importPath));
15474
16110
  moduleFile.localImports.push(importPath);
15475
16111
  } else addExternalImport(config, compilerCtx, buildCtx, moduleFile, moduleFile.sourceFilePath, importPath, resolveCollections, !importNode.importClause);
15476
16112
  }
@@ -15536,7 +16172,8 @@ const updateModule = (config, compilerCtx, buildCtx, tsSourceFile, sourceFileTex
15536
16172
  const prevModuleFile = getModule(compilerCtx, sourceFilePath);
15537
16173
  if (prevModuleFile && prevModuleFile.staticSourceFileText === sourceFileText) return prevModuleFile;
15538
16174
  const srcDirPath = dirname$1(sourceFilePath);
15539
- emitFilePath = normalizePath(join$2(srcDirPath, basename$1(emitFilePath)));
16175
+ const emitFileName = basename$1(emitFilePath);
16176
+ emitFilePath = normalizePath(join$2(srcDirPath, emitFileName));
15540
16177
  const moduleFile = createModule(tsSourceFile, sourceFileText, emitFilePath);
15541
16178
  if (emitFilePath.endsWith(".js.map")) {
15542
16179
  moduleFile.sourceMapPath = emitFilePath;
@@ -15588,15 +16225,18 @@ const updateModule = (config, compilerCtx, buildCtx, tsSourceFile, sourceFileTex
15588
16225
  //#region src/compiler/transformers/collection/parse-collection-components.ts
15589
16226
  const parseCollectionComponents = (config, compilerCtx, buildCtx, collectionDir, collectionManifest, collection) => {
15590
16227
  if (collectionManifest.mixins) collectionManifest.mixins.forEach((mixinPath) => {
15591
- transpileCollectionModule(config, compilerCtx, buildCtx, collection, join$2(collectionDir, mixinPath));
16228
+ const fullPath = join$2(collectionDir, mixinPath);
16229
+ transpileCollectionModule(config, compilerCtx, buildCtx, collection, fullPath);
15592
16230
  });
15593
16231
  if (collectionManifest.entries) collectionManifest.entries.forEach((entryPath) => {
15594
- transpileCollectionModule(config, compilerCtx, buildCtx, collection, join$2(collectionDir, entryPath));
16232
+ const componentPath = join$2(collectionDir, entryPath);
16233
+ transpileCollectionModule(config, compilerCtx, buildCtx, collection, componentPath);
15595
16234
  });
15596
16235
  };
15597
16236
  const transpileCollectionModule = (config, compilerCtx, buildCtx, collection, inputFileName) => {
15598
16237
  const sourceText = compilerCtx.fs.readFileSync(inputFileName);
15599
- 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);
15600
16240
  };
15601
16241
  //#endregion
15602
16242
  //#region src/compiler/transformers/collection/parse-collection-manifest.ts
@@ -15626,7 +16266,8 @@ const parseCollectionDependencies = (collectionManifest) => {
15626
16266
  };
15627
16267
  const parseGlobal = (config, compilerCtx, buildCtx, collectionDir, collectionManifest, collection) => {
15628
16268
  if (typeof collectionManifest.global !== "string") return;
15629
- 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);
15630
16271
  };
15631
16272
  const parseBundles = (collectionManifest) => {
15632
16273
  if (invalidArrayData(collectionManifest.bundles)) return [];
@@ -15644,12 +16285,14 @@ const parseCollection = (config, compilerCtx, buildCtx, moduleId, pkgJsonFilePat
15644
16285
  let collection = compilerCtx.collections.find((c) => c.collectionName === collectionName);
15645
16286
  if (collection != null) return collection;
15646
16287
  const collectionPackageRootDir = dirname$1(pkgJsonFilePath);
15647
- const collectionFilePath = join$2(collectionPackageRootDir, pkgData.collection ?? pkgData.collection);
16288
+ const collectionManifestPath = pkgData.collection ?? pkgData.collection;
16289
+ const collectionFilePath = join$2(collectionPackageRootDir, collectionManifestPath);
15648
16290
  const relPath = relative$1(config.rootDir, collectionFilePath);
15649
16291
  config.logger.debug(`load collection: ${collectionName}, ${relPath}`);
15650
16292
  const collectionJsonStr = compilerCtx.fs.readFileSync(collectionFilePath);
15651
16293
  if (!collectionJsonStr) return null;
15652
- 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);
15653
16296
  collection.moduleId = moduleId;
15654
16297
  if (pkgData.module && pkgData.module !== pkgData.main) collection.hasExports = true;
15655
16298
  collection.moduleDir = collectionPackageRootDir;
@@ -15693,7 +16336,8 @@ const resolveAndIngestCollection = (config, compilerCtx, buildCtx, containingFil
15693
16336
  })) return;
15694
16337
  buildCtx.collections.push(collection);
15695
16338
  if (Array.isArray(collection.dependencies)) collection.dependencies.forEach((dependencyModuleId) => {
15696
- resolveAndIngestCollection(config, compilerCtx, buildCtx, dirname$1(pkgJsonFilePath), dependencyModuleId, resolveCollections);
16339
+ const resolveFromDir = dirname$1(pkgJsonFilePath);
16340
+ resolveAndIngestCollection(config, compilerCtx, buildCtx, resolveFromDir, dependencyModuleId, resolveCollections);
15697
16341
  });
15698
16342
  };
15699
16343
  /**
@@ -16019,6 +16663,18 @@ const validateUniqueTagNames = (config, buildCtx, cmp) => {
16019
16663
  //#endregion
16020
16664
  //#region src/compiler/transpile/run-program.ts
16021
16665
  /**
16666
+ * In dev mode, downgrade unused-variable diagnostics to warnings so they don't fail the build
16667
+ * while a component is mid-edit.
16668
+ *
16669
+ * @param config - the validated Stencil configuration
16670
+ * @param diags - the diagnostics to relax in place
16671
+ */
16672
+ const applyDevModeRelaxation = (config, diags) => {
16673
+ if (config.devMode) diags.forEach((diag) => {
16674
+ if (diag.code === "6133" || diag.code === "6192") diag.level = "warn";
16675
+ });
16676
+ };
16677
+ /**
16022
16678
  * Run the TypeScript program to transpile source files.
16023
16679
  *
16024
16680
  * @param config - the validated Stencil configuration
@@ -16039,6 +16695,21 @@ const runTsProgram = async (config, compilerCtx, buildCtx, tsBuilder) => {
16039
16695
  const tsTypeChecker = tsProgram.getTypeChecker();
16040
16696
  const typesOutputTarget = config.outputTargets.filter(isOutputTargetTypes);
16041
16697
  const emittedDts = [];
16698
+ if (buildCtx.isRebuild && buildCtx.hasScriptChanges && config.validateTypes) {
16699
+ const emitBuilder = tsBuilder;
16700
+ let affected = emitBuilder.getSemanticDiagnosticsOfNextAffectedFile?.();
16701
+ while (affected) {
16702
+ if ("fileName" in affected.affected) {
16703
+ const fileName = normalizePath(affected.affected.fileName);
16704
+ if (!fileName.includes("node_modules") && !fileName.endsWith(".d.ts") && fileName.startsWith(normalizePath(config.srcDir))) {
16705
+ const tsSemantic = loadTypeScriptDiagnostics(affected.result);
16706
+ applyDevModeRelaxation(config, tsSemantic);
16707
+ buildCtx.diagnostics.push(...tsSemantic);
16708
+ }
16709
+ }
16710
+ affected = emitBuilder.getSemanticDiagnosticsOfNextAffectedFile?.();
16711
+ }
16712
+ }
16042
16713
  const emitCallback = (emitFilePath, data, _w, _e, tsSourceFiles) => {
16043
16714
  if (emitFilePath.includes("e2e.") || emitFilePath.includes("spec.") || emitFilePath.endsWith("e2e.d.ts") || emitFilePath.endsWith("spec.d.ts")) return;
16044
16715
  if (emitFilePath.endsWith(".js") || emitFilePath.endsWith("js.map")) updateModule(config, compilerCtx, buildCtx, tsSourceFiles[0], data, emitFilePath, tsTypeChecker, null);
@@ -16087,7 +16758,8 @@ const runTsProgram = async (config, compilerCtx, buildCtx, tsBuilder) => {
16087
16758
  const changedmodules = Array.from(compilerCtx.changedModules.keys());
16088
16759
  buildCtx.debug("Transpiled modules: " + JSON.stringify(changedmodules, null, "\n"));
16089
16760
  buildCtx.moduleFiles = Array.from(compilerCtx.moduleMap.values());
16090
- const { components: filteredComponents, excludedComponents } = filterExcludedComponents(getComponentsFromModules(buildCtx.moduleFiles), config);
16761
+ const allComponents = getComponentsFromModules(buildCtx.moduleFiles);
16762
+ const { components: filteredComponents, excludedComponents } = filterExcludedComponents(allComponents, config);
16091
16763
  buildCtx.components = filteredComponents;
16092
16764
  if (excludedComponents.length > 0 && typesOutputTarget.length > 0) excludedComponents.forEach((cmp) => {
16093
16765
  const srcPath = normalizePath(cmp.sourceFilePath);
@@ -16126,36 +16798,15 @@ const validateTypesAfterGeneration = async (config, compilerCtx, buildCtx, tsBui
16126
16798
  needsRebuild: true
16127
16799
  };
16128
16800
  }
16129
- if (config.validateTypes) {
16130
- const applyDevModeRelaxation = (diags) => {
16131
- if (config.devMode) diags.forEach((d) => {
16132
- if (d.code === "6133" || d.code === "6192") d.level = "warn";
16133
- });
16134
- };
16135
- if (buildCtx.isRebuild) {
16136
- const emitBuilder = tsBuilder;
16137
- let affected = emitBuilder.getSemanticDiagnosticsOfNextAffectedFile?.();
16138
- while (affected) {
16139
- if ("fileName" in affected.affected) {
16140
- const fileName = normalizePath(affected.affected.fileName);
16141
- if (!fileName.includes("node_modules") && !fileName.endsWith(".d.ts") && fileName.startsWith(normalizePath(config.srcDir))) {
16142
- const tsSemantic = loadTypeScriptDiagnostics(affected.result);
16143
- applyDevModeRelaxation(tsSemantic);
16144
- buildCtx.diagnostics.push(...tsSemantic);
16145
- }
16146
- }
16147
- affected = emitBuilder.getSemanticDiagnosticsOfNextAffectedFile?.();
16148
- }
16149
- } else {
16150
- const sourceFiles = tsProgram.getSourceFiles().filter((sf) => {
16151
- const fileName = normalizePath(sf.fileName);
16152
- return !fileName.includes("node_modules") && !fileName.endsWith(".d.ts") && fileName.startsWith(normalizePath(config.srcDir));
16153
- });
16154
- for (const sourceFile of sourceFiles) {
16155
- const tsSemantic = loadTypeScriptDiagnostics(tsProgram.getSemanticDiagnostics(sourceFile));
16156
- applyDevModeRelaxation(tsSemantic);
16157
- buildCtx.diagnostics.push(...tsSemantic);
16158
- }
16801
+ if (config.validateTypes && !buildCtx.isRebuild) {
16802
+ const sourceFiles = tsProgram.getSourceFiles().filter((sf) => {
16803
+ const fileName = normalizePath(sf.fileName);
16804
+ return !fileName.includes("node_modules") && !fileName.endsWith(".d.ts") && fileName.startsWith(normalizePath(config.srcDir));
16805
+ });
16806
+ for (const sourceFile of sourceFiles) {
16807
+ const tsSemantic = loadTypeScriptDiagnostics(tsProgram.getSemanticDiagnostics(sourceFile));
16808
+ applyDevModeRelaxation(config, tsSemantic);
16809
+ buildCtx.diagnostics.push(...tsSemantic);
16159
16810
  }
16160
16811
  }
16161
16812
  const hasTypesChanged = await generateAppTypes(config, compilerCtx, buildCtx, "src");
@@ -16263,7 +16914,10 @@ const getComponentsUpdated = (compilerCtx, buildCtx) => {
16263
16914
  const changedScriptFiles = [];
16264
16915
  const checkedFiles = /* @__PURE__ */ new Set();
16265
16916
  const allModuleFiles = buildCtx.moduleFiles.filter((m) => m.localImports && m.localImports.length > 0);
16266
- 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
+ }
16267
16921
  const tags = changedScriptFiles.reduce((acc, changedTsFile) => {
16268
16922
  const moduleFile = compilerCtx.moduleMap.get(changedTsFile);
16269
16923
  if (moduleFile != null) moduleFile.cmps.forEach((cmp) => {
@@ -16448,43 +17102,47 @@ function generateBuildStats(config, buildCtx) {
16448
17102
  const buildResults = buildCtx.buildResults;
16449
17103
  try {
16450
17104
  if (buildResults.hasError) return err({ diagnostics: buildResults.diagnostics });
16451
- else return ok({
16452
- timestamp: buildResults.timestamp,
16453
- compiler: {
16454
- name: config.sys.name,
16455
- version: config.sys.version
16456
- },
16457
- app: {
16458
- namespace: config.namespace,
16459
- fsNamespace: config.fsNamespace,
16460
- components: Object.keys(buildResults.componentGraph ?? {}).length,
16461
- entries: Object.keys(buildResults.componentGraph ?? {}).length,
16462
- bundles: buildResults.outputs.reduce((total, en) => total + en.files.length, 0),
16463
- outputs: getAppOutputs(config, buildResults)
16464
- },
16465
- options: {
16466
- minifyJs: !!config.minifyJs,
16467
- minifyCss: !!config.minifyCss
16468
- },
16469
- formats: {
16470
- esmBrowser: sanitizeBundlesForStats(buildCtx.esmBrowserComponentBundle),
16471
- esm: sanitizeBundlesForStats(buildCtx.esmComponentBundle),
16472
- commonjs: sanitizeBundlesForStats(buildCtx.commonJsComponentBundle)
16473
- },
16474
- components: getComponentsFileMap(config, buildCtx),
16475
- entries: buildCtx.entryModules,
16476
- componentGraph: buildResults.componentGraph ?? {},
16477
- sourceGraph: getSourceGraph(config, buildCtx),
16478
- rolldownResults: buildCtx.rolldownResults ?? { modules: [] },
16479
- collections: getCollections(config, buildCtx)
16480
- });
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
+ }
16481
17138
  } catch (e) {
16482
- return err({ diagnostics: [{
17139
+ const diagnostic = {
16483
17140
  level: `error`,
16484
17141
  lines: [],
16485
17142
  messageText: `Generate Build Stats Error: ` + e,
16486
17143
  type: `build`
16487
- }] });
17144
+ };
17145
+ return err({ diagnostics: [diagnostic] });
16488
17146
  }
16489
17147
  }
16490
17148
  /**
@@ -16660,10 +17318,13 @@ const buildDone = async (config, compilerCtx, buildCtx, aborted) => {
16660
17318
  */
16661
17319
  const logHmr = (logger, hmr) => {
16662
17320
  if (hmr.componentsUpdated) cleanupUpdateMsg(logger, `updated component`, hmr.componentsUpdated);
16663
- if (hmr.inlineStylesUpdated) cleanupUpdateMsg(logger, `updated style`, hmr.inlineStylesUpdated.map((s) => s.styleTag).reduce((arr, v) => {
16664
- if (!arr.includes(v)) arr.push(v);
16665
- return arr;
16666
- }, []));
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
+ }
16667
17328
  if (hmr.externalStylesUpdated) cleanupUpdateMsg(logger, `updated stylesheet`, hmr.externalStylesUpdated);
16668
17329
  if (hmr.imagesUpdated) cleanupUpdateMsg(logger, `updated image`, hmr.imagesUpdated);
16669
17330
  };
@@ -16760,7 +17421,7 @@ const getPackageJsonRecommendations = (config, compilerCtx) => {
16760
17421
  * @returns an empty Promise
16761
17422
  */
16762
17423
  const validateBuildPackageJson = async (config, compilerCtx, buildCtx) => {
16763
- if (config.watch || buildCtx.packageJson == null) return;
17424
+ if (config.watch || config.devMode || buildCtx.packageJson == null) return;
16764
17425
  validatePackageJson(config, compilerCtx, buildCtx);
16765
17426
  const stencilCollectionOutputTargets = config.outputTargets.filter(isOutputTargetCollection);
16766
17427
  await Promise.all(stencilCollectionOutputTargets.map((stencilCollectionOT) => validateCollectionFields(config, compilerCtx, buildCtx, stencilCollectionOT)));
@@ -16900,26 +17561,30 @@ const validateCollectionFields = async (config, compilerCtx, buildCtx, outputTar
16900
17561
  * @param outputTarget the collection output target to validate against
16901
17562
  */
16902
17563
  const validatePackageFiles = async (config, compilerCtx, buildCtx, outputTarget) => {
16903
- if (!config.devMode && Array.isArray(buildCtx.packageJson.files)) {
16904
- const actualDistDir = normalizePath(relative$1(config.rootDir, outputTarget.dir));
16905
- if (!buildCtx.packageJson.files.some((userPath) => {
16906
- const normalizedUserPath = normalizePath(userPath).replace(/\/$/, "").replace(/^\.\//, "");
16907
- const normalizedDistDir = actualDistDir.replace(/\/$/, "").replace(/^\.\//, "");
16908
- if (normalizedUserPath === normalizedDistDir) return true;
16909
- const userPathWithSlash = normalizedUserPath + "/";
16910
- if (normalizedDistDir.startsWith(userPathWithSlash)) return true;
16911
- return false;
16912
- })) {
16913
- packageJsonWarn(config, compilerCtx, buildCtx, `package.json "files" array must contain the distribution directory "${actualDistDir}/" when generating a distribution.`, `"files"`);
16914
- return;
16915
- }
16916
- await Promise.all(buildCtx.packageJson.files.map(async (pkgFile) => {
16917
- if (!isGlob(pkgFile)) {
16918
- const absPath = join$2(dirname$1(config.packageJsonFilePath), pkgFile);
16919
- if (!await compilerCtx.fs.access(absPath)) packageJsonError(config, compilerCtx, buildCtx, `Unable to find "${pkgFile}" within the package.json "files" array.`, `"${pkgFile}"`);
16920
- }
16921
- }));
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;
16922
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
+ }));
16923
17588
  };
16924
17589
  /**
16925
17590
  * Check that the `collection` field is set correctly in `package.json` for the
@@ -16932,7 +17597,10 @@ const validatePackageFiles = async (config, compilerCtx, buildCtx, outputTarget)
16932
17597
  const validateCollectionField = (config, compilerCtx, buildCtx, outputTarget) => {
16933
17598
  if (outputTarget.dir) {
16934
17599
  const collectionRel = normalizePath(join$2(relative$1(config.rootDir, outputTarget.dir), COLLECTION_MANIFEST_FILE_NAME), false);
16935
- 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
+ }
16936
17604
  }
16937
17605
  };
16938
17606
  /**
@@ -16976,7 +17644,8 @@ const validateManifestJson = (config, compilerCtx, buildCtx) => {
16976
17644
  try {
16977
17645
  const manifestContent = await compilerCtx.fs.readFile(manifestFilePath);
16978
17646
  if (manifestContent) try {
16979
- await validateManifestJsonData(compilerCtx, buildCtx, manifestFilePath, JSON.parse(manifestContent));
17647
+ const manifestData = JSON.parse(manifestContent);
17648
+ await validateManifestJsonData(compilerCtx, buildCtx, manifestFilePath, manifestData);
16980
17649
  } catch (e) {
16981
17650
  const err = buildError(buildCtx.diagnostics);
16982
17651
  err.header = `Invalid manifest.json: ${e}`;
@@ -16997,7 +17666,8 @@ const validateManifestJsonIcon = async (compilerCtx, buildCtx, manifestFilePath,
16997
17666
  return;
16998
17667
  }
16999
17668
  if (iconSrc.startsWith("/")) iconSrc = iconSrc.slice(1);
17000
- const iconPath = join$2(dirname$1(manifestFilePath), iconSrc);
17669
+ const manifestDir = dirname$1(manifestFilePath);
17670
+ const iconPath = join$2(manifestDir, iconSrc);
17001
17671
  if (!await compilerCtx.fs.access(iconPath)) {
17002
17672
  const msg = `Unable to find manifest icon "${manifestIcon.src}"`;
17003
17673
  buildJsonFileError(compilerCtx, buildCtx.diagnostics, manifestFilePath, msg, `"${manifestIcon.src}"`);
@@ -17059,11 +17729,18 @@ const generateRootExport = (config, buildCtx, loaderBundle, standalone, types) =
17059
17729
  if (!(currentImport && isValidRootExport(config, currentImport, loaderBundle, standalone))) {
17060
17730
  const primaryDir = loaderBundle?.dir ?? standalone?.dir;
17061
17731
  if (primaryDir) {
17062
- execSync(`npm pkg set "exports[.][import]"="${normalizePath(relative$1(config.rootDir, join$2(primaryDir, "index.js")))}"`);
17063
- 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
+ }
17064
17738
  }
17065
17739
  }
17066
- 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
+ }
17067
17744
  };
17068
17745
  /**
17069
17746
  * Check if the current root export import path is valid
@@ -17108,12 +17785,17 @@ const ensureRelativePrefix = (path) => {
17108
17785
  */
17109
17786
  const generateLoaderExport = (config, loaderBundle, types) => {
17110
17787
  const esmDir = join$2(loaderBundle.dir, "esm");
17111
- 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}"`);
17112
17790
  if (loaderBundle.cjs) {
17113
17791
  const cjsDir = join$2(loaderBundle.dir, "cjs");
17114
- 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}"`);
17115
17798
  }
17116
- if (types?.dir) execSync(`npm pkg set "exports[./loader][types]"="${ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(types.dir, "loader.d.ts"))))}"`);
17117
17799
  };
17118
17800
  /**
17119
17801
  * Generate per-component exports for standalone output.
@@ -17307,8 +17989,10 @@ const compilerRequest = async (config, compilerCtx, data) => {
17307
17989
  return results;
17308
17990
  }
17309
17991
  } catch (e) {
17310
- if (e) if (e instanceof Error && e.stack) results.content = `/*\n${e.stack}\n*/`;
17311
- 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
+ }
17312
17996
  results.status = 500;
17313
17997
  }
17314
17998
  return results;
@@ -17725,7 +18409,8 @@ const createWatchBuild = async (config, compilerCtx) => {
17725
18409
  filesAdded.forEach((f) => currentlyBuildingFiles.add(f));
17726
18410
  filesUpdated.forEach((f) => currentlyBuildingFiles.add(f));
17727
18411
  filesDeleted.forEach((f) => currentlyBuildingFiles.add(f));
17728
- await onBuild(incrementalCompiler.rebuild());
18412
+ const tsBuilder = incrementalCompiler.rebuild();
18413
+ await onBuild(tsBuilder);
17729
18414
  } finally {
17730
18415
  currentlyBuildingFiles.clear();
17731
18416
  isBuilding = false;
@@ -17765,7 +18450,7 @@ const createWatchBuild = async (config, compilerCtx) => {
17765
18450
  if (!compilerCtx.fs.accessSync(key)) compilerCtx.moduleMap.delete(key);
17766
18451
  }
17767
18452
  });
17768
- new Set([...filesUpdated, ...filesAdded]).forEach((filePath) => {
18453
+ (/* @__PURE__ */ new Set([...filesUpdated, ...filesAdded])).forEach((filePath) => {
17769
18454
  compilerCtx.addWatchFile(filePath);
17770
18455
  });
17771
18456
  dirsAdded.clear();
@@ -17778,7 +18463,8 @@ const createWatchBuild = async (config, compilerCtx) => {
17778
18463
  const result = await build(config, compilerCtx, buildCtx, tsBuilder);
17779
18464
  if (result === null) {
17780
18465
  incrementalCompiler.refreshRootNames();
17781
- await onBuild(incrementalCompiler.rebuild());
18466
+ const freshTsBuilder = incrementalCompiler.rebuild();
18467
+ await onBuild(freshTsBuilder);
17782
18468
  return;
17783
18469
  }
17784
18470
  if (!result.hasError) isRebuild = true;
@@ -17806,7 +18492,8 @@ const createWatchBuild = async (config, compilerCtx) => {
17806
18492
  ...(config.watchExternalDirs || []).map((dir) => watchFiles(compilerCtx, dir))
17807
18493
  ]);
17808
18494
  incrementalCompiler = new IncrementalCompiler(config);
17809
- await onBuild(incrementalCompiler.rebuild());
18495
+ const tsBuilder = incrementalCompiler.rebuild();
18496
+ await onBuild(tsBuilder);
17810
18497
  return watchWaiter;
17811
18498
  };
17812
18499
  /**
@@ -17849,9 +18536,7 @@ const createWatchBuild = async (config, compilerCtx) => {
17849
18536
  case "fileUpdate":
17850
18537
  filesUpdated.add(filePath);
17851
18538
  break;
17852
- case "fileDelete":
17853
- filesDeleted.add(filePath);
17854
- break;
18539
+ case "fileDelete": filesDeleted.add(filePath);
17855
18540
  }
17856
18541
  if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) tsFilesToInvalidate.add(filePath);
17857
18542
  config.logger.debug(`WATCH_BUILD::fs_event_change - type=${eventKind}, path=${filePath}, time=${(/* @__PURE__ */ new Date()).getTime()}`);
@@ -18116,7 +18801,7 @@ var Cache = class {
18116
18801
  }
18117
18802
  };
18118
18803
  const MAX_FAILED = 100;
18119
- const ONE_DAY = 1e3 * 60 * 60 * 24;
18804
+ const ONE_DAY = 864e5;
18120
18805
  const ONE_WEEK = ONE_DAY * 7;
18121
18806
  const EXP_STORAGE_KEY = `last_clear_expired_cache`;
18122
18807
  const CACHE_DIR_README = `# Stencil Cache Directory
@@ -18275,6 +18960,9 @@ const validateDocs$1 = (config, diagnostics, userOutputs) => {
18275
18960
  userOutputs.filter(isOutputTargetDocsCustomElementsManifest).forEach((cemOutput) => {
18276
18961
  docsOutputs.push(validateCustomElementsManifestOutputTarget(config, cemOutput));
18277
18962
  });
18963
+ userOutputs.filter(isOutputTargetDocsAgentSkill).forEach((agentSkillOutput) => {
18964
+ docsOutputs.push(validateAgentSkillOutputTarget(config, agentSkillOutput));
18965
+ });
18278
18966
  return docsOutputs;
18279
18967
  };
18280
18968
  const validateReadmeOutputTarget = (config, outputTarget) => {
@@ -18314,6 +19002,13 @@ const validateVScodeDocsOutputTarget = (config, diagnostics, outputTarget) => {
18314
19002
  if (!isBoolean$1(outputTarget.skipInDev)) outputTarget.skipInDev = !config._docsFlag;
18315
19003
  return outputTarget;
18316
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
+ };
18317
19012
  const validateCustomElementsManifestOutputTarget = (config, outputTarget) => {
18318
19013
  if (!isString$1(outputTarget.file)) outputTarget.file = "custom-elements.json";
18319
19014
  if (!isAbsolute$1(outputTarget.file)) outputTarget.file = join$2(config.rootDir, outputTarget.file);
@@ -18342,9 +19037,10 @@ const validateGlobalStyle = (config, userOutputs) => {
18342
19037
  const input = isString$1(outputTarget.input) ? getAbsolutePath(config, outputTarget.input) : config.globalStyle ?? void 0;
18343
19038
  let fileName;
18344
19039
  if (isString$1(outputTarget.fileName)) fileName = outputTarget.fileName;
18345
- else if (input) if (isString$1(outputTarget.input)) fileName = basename(input);
18346
- else fileName = `${config.fsNamespace}.css`;
18347
- 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`;
18348
19044
  const validInjectValues = [
18349
19045
  "none",
18350
19046
  "client",
@@ -18367,9 +19063,10 @@ const validateGlobalStyle = (config, userOutputs) => {
18367
19063
  //#region src/compiler/config/outputs/validate-lazy.ts
18368
19064
  const validateLazy = (config, userOutputs) => {
18369
19065
  return userOutputs.filter(isOutputTargetDistLazy).map((o) => {
19066
+ const dir = getAbsolutePath(config, o.dir || join$2("dist", config.fsNamespace));
18370
19067
  return {
18371
19068
  type: DIST_LAZY,
18372
- esmDir: getAbsolutePath(config, o.dir || join$2("dist", config.fsNamespace)),
19069
+ esmDir: dir,
18373
19070
  isBrowserBuild: true,
18374
19071
  empty: isBoolean$1(o.empty) ? o.empty : true
18375
19072
  };
@@ -18433,7 +19130,8 @@ const validateLoaderBundle = (config, diagnostics, userOutputs) => {
18433
19130
  if (!config.devMode || !loaderBundleOutput.skipInDev) {
18434
19131
  const esmDir = join$2(loaderBundleOutput.dir, "esm");
18435
19132
  const cjsDir = loaderBundleOutput.cjs ? join$2(loaderBundleOutput.dir, "cjs") : void 0;
18436
- 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");
18437
19135
  outputs.push({
18438
19136
  type: DIST_LAZY,
18439
19137
  esmDir,
@@ -19245,6 +19943,8 @@ const validateConfig = (userConfig = {}, bootstrapConfig) => {
19245
19943
  const ldp = validatedConfig.compat.lightDomPatches;
19246
19944
  if (ldp === void 0) validatedConfig.compat.lightDomPatches = true;
19247
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;
19248
19948
  setBooleanConfig(validatedConfig, "watch", false);
19249
19949
  setBooleanConfig(validatedConfig, "profile", validatedConfig.devMode);
19250
19950
  setBooleanConfig(validatedConfig, "writeLog", false);
@@ -19252,8 +19952,6 @@ const validateConfig = (userConfig = {}, bootstrapConfig) => {
19252
19952
  setBooleanConfig(validatedConfig, "autoprefixCss", false);
19253
19953
  setBooleanConfig(validatedConfig, "validateTypes", !validatedConfig._isTesting);
19254
19954
  setBooleanConfig(validatedConfig, "allowInlineScripts", true);
19255
- setBooleanConfig(validatedConfig, "suppressReservedPublicNameWarnings", false);
19256
- setBooleanConfig(validatedConfig, "suppressReservedEventNameWarnings", false);
19257
19955
  if (!isString$1(validatedConfig.taskQueue)) validatedConfig.taskQueue = "async";
19258
19956
  if (!validatedConfig.env) validatedConfig.env = {};
19259
19957
  validateOutputTargets(validatedConfig, diagnostics);
@@ -19263,6 +19961,7 @@ const validateConfig = (userConfig = {}, bootstrapConfig) => {
19263
19961
  else validatedConfig.bundles = [];
19264
19962
  if (!Array.isArray(validatedConfig.excludeComponents)) validatedConfig.excludeComponents = [];
19265
19963
  if (!Array.isArray(validatedConfig.collections)) validatedConfig.collections = [];
19964
+ if (!Array.isArray(validatedConfig.modes)) validatedConfig.modes = [];
19266
19965
  validateWorkers(validatedConfig);
19267
19966
  setBooleanConfig(validatedConfig, "devInspector", validatedConfig.devMode);
19268
19967
  setBooleanConfig(validatedConfig, "enableCache", true);
@@ -20205,7 +20904,8 @@ const autoprefixCss = async (cssText, opts, filePath, minify = false) => {
20205
20904
  diagnostics: []
20206
20905
  };
20207
20906
  try {
20208
- 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);
20209
20909
  output.output = transform({
20210
20910
  filename: filePath ?? "style.css",
20211
20911
  code: Buffer.from(cssText),
@@ -20489,7 +21189,8 @@ const parseCss = (css, filePath) => {
20489
21189
  };
20490
21190
  const atquery = (name) => {
20491
21191
  const pos = position();
20492
- const m = match(new RegExp("^@" + name + " *([^{]+)"));
21192
+ const regex = new RegExp("^@" + name + " *([^{]+)");
21193
+ const m = match(regex);
20493
21194
  if (!m) return null;
20494
21195
  const media = trim(m[1]);
20495
21196
  if (!open()) return error(`@${name} missing '{'`);
@@ -20508,7 +21209,8 @@ const parseCss = (css, filePath) => {
20508
21209
  */
20509
21210
  const nestedAtQuery = (name) => {
20510
21211
  const pos = position();
20511
- const m = match(new RegExp("^@" + name + " *([^{]+)"));
21212
+ const regex = new RegExp("^@" + name + " *([^{]+)");
21213
+ const m = match(regex);
20512
21214
  if (!m) return null;
20513
21215
  const media = trim(m[1]);
20514
21216
  const decls = declarations();
@@ -20766,8 +21468,10 @@ const serializeCssVisitNode = (opts, node, index, len) => {
20766
21468
  const nodeType = node.type;
20767
21469
  if (nodeType === 4) return serializeCssDeclaration(node, index, len);
20768
21470
  if (nodeType === 14) return serializeCssRule(opts, node);
20769
- if (nodeType === 1) if (node.comment?.[0] === "!") return `/*${node.comment}*/`;
20770
- else return "";
21471
+ if (nodeType === 1) {
21472
+ if (node.comment?.[0] === "!") return `/*${node.comment}*/`;
21473
+ else return "";
21474
+ }
20771
21475
  if (nodeType === 10) return serializeCssMedia(opts, node);
20772
21476
  if (nodeType === 11) return serializeCssContainer(opts, node);
20773
21477
  if (nodeType === 8) return serializeCssKeyframes(opts, node);
@@ -20999,7 +21703,8 @@ const crawlAnchorsForNextUrls = (prerenderConfig, diagnostics, baseUrl, currentU
20999
21703
  return standardFilterAnchor(diagnostics, anchor, currentUrl);
21000
21704
  }).map((anchor) => {
21001
21705
  if (typeof prerenderConfig.normalizeUrl === "function") try {
21002
- 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);
21003
21708
  } catch (e) {
21004
21709
  catchError(diagnostics, e);
21005
21710
  }
@@ -21101,7 +21806,7 @@ const extname$1 = (str) => {
21101
21806
  const parts = str.split(".");
21102
21807
  return parts[parts.length - 1].toLowerCase();
21103
21808
  };
21104
- const SKIP_EXT = new Set([
21809
+ const SKIP_EXT = /* @__PURE__ */ new Set([
21105
21810
  "zip",
21106
21811
  "rar",
21107
21812
  "tar",
@@ -21145,8 +21850,10 @@ const getPrerenderConfig = async (diagnostics, prerenderConfigPath) => {
21145
21850
  const results = await nodeRequire(prerenderConfigPath);
21146
21851
  diagnostics.push(...results.diagnostics);
21147
21852
  const mod = results.module?.default ?? results.module;
21148
- if (mod != null && typeof mod === "object") if (mod.config != null && typeof mod.config === "object") Object.assign(prerenderConfig, mod.config);
21149
- 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
+ }
21150
21857
  }
21151
21858
  return prerenderConfig;
21152
21859
  };
@@ -21203,7 +21910,8 @@ const optimizeJs = async (inputOpts) => {
21203
21910
  sourceMap: null
21204
21911
  };
21205
21912
  try {
21206
- const minifyOpts = getTerserOptions({}, "latest", !!inputOpts.pretty);
21913
+ const prettyOutput = !!inputOpts.pretty;
21914
+ const minifyOpts = getTerserOptions({}, "latest", prettyOutput);
21207
21915
  const minifyResults = await minifyJs(inputOpts.input, minifyOpts);
21208
21916
  if (minifyResults.diagnostics.length > 0) result.diagnostics.push(...minifyResults.diagnostics);
21209
21917
  else {
@@ -21309,7 +22017,9 @@ s&&((s['data-opts']=s['data-opts']||{}).exclude=__EXCLUDE__);
21309
22017
  const addModulePreloads = (doc, hydrateOpts, hydrateResults, componentGraph) => {
21310
22018
  if (!componentGraph) return false;
21311
22019
  const staticComponents = hydrateOpts.staticComponents || [];
21312
- 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);
21313
22023
  return true;
21314
22024
  };
21315
22025
  const removeModulePreloads = (doc) => {
@@ -21418,14 +22128,16 @@ const hashPageStateAstAssets = async (sys, hydrateOpts, appDir, currentUrl, page
21418
22128
  };
21419
22129
  const getAttrUrls = (attrName, attrValue) => {
21420
22130
  const srcValues = [];
21421
- if (isString$1(attrValue)) if (attrName.toLowerCase() === "srcset") attrValue.split(",").map((a) => a.trim()).filter((a) => a.length > 0).forEach((src) => {
21422
- const spaceSplt = src.split(" ");
21423
- if (spaceSplt[0].length > 0) srcValues.push({
21424
- src: spaceSplt[0],
21425
- 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
+ });
21426
22138
  });
21427
- });
21428
- else srcValues.push({ src: attrValue });
22139
+ else srcValues.push({ src: attrValue });
22140
+ }
21429
22141
  return srcValues;
21430
22142
  };
21431
22143
  const setAttrUrls = (url, descriptor) => {
@@ -21550,10 +22262,12 @@ const prerenderWorker = async (sys, prerenderRequest) => {
21550
22262
  [s.id]: JSON.parse(s.content),
21551
22263
  components: hydrateResults.components.map((c) => c.tag)
21552
22264
  };
21553
- const dataFilePath = join$2(pageDir, `${s.id}.json`);
22265
+ const dataFileName = `${s.id}.json`;
22266
+ const dataFilePath = join$2(pageDir, dataFileName);
21554
22267
  await sys.writeFile(dataFilePath, JSON.stringify(data));
21555
22268
  } else {
21556
- const contentFilePath = join$2(pageDir, `${s.id}.txt`);
22269
+ const contentFileName = `${s.id}.txt`;
22270
+ const contentFilePath = join$2(pageDir, contentFileName);
21557
22271
  await sys.writeFile(contentFilePath, s.content);
21558
22272
  }
21559
22273
  }));
@@ -21661,7 +22375,8 @@ const transformCssToEsm = async (input) => {
21661
22375
  * @returns transformed ESM output
21662
22376
  */
21663
22377
  const transformCssToEsmSync = (input) => {
21664
- return generateTransformCssToEsm(input, transformCssToEsmModule(input));
22378
+ const results = transformCssToEsmModule(input);
22379
+ return generateTransformCssToEsm(input, results);
21665
22380
  };
21666
22381
  /**
21667
22382
  * Performs the actual transformation from CSS to ESM
@@ -21681,7 +22396,7 @@ const transformCssToEsmModule = (input) => {
21681
22396
  };
21682
22397
  if (input.docs) parseStyleDocs(results.styleDocs, input.input, input.mode);
21683
22398
  try {
21684
- const varNames = new Set([results.defaultVarName]);
22399
+ const varNames = /* @__PURE__ */ new Set([results.defaultVarName]);
21685
22400
  if (isString$1(input.tag) && input.encapsulation === "scoped") {
21686
22401
  const scopeId = getScopeId(input.tag, input.mode);
21687
22402
  results.styleText = scopeCss(results.styleText, scopeId, false);
@@ -21716,7 +22431,7 @@ const transformCssToEsmModule = (input) => {
21716
22431
  */
21717
22432
  const generateTransformCssToEsm = (input, results) => {
21718
22433
  const s = new MagicString("");
21719
- 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, "\\${");
21720
22435
  if (input.addTagTransformers) results.styleText = addTagTransformToCssString(results.styleText, input.tags);
21721
22436
  results.styleText = stripCssComments(results.styleText);
21722
22437
  if (input.module === "cjs") {
@@ -21758,7 +22473,7 @@ const getCssToEsmImports = (varNames, cssText, filePath, modeName) => {
21758
22473
  const cssImports = [];
21759
22474
  if (!cssText.includes("@import")) return cssImports;
21760
22475
  cssText = stripCssComments(cssText);
21761
- const dir = path$1.dirname(filePath);
22476
+ const dir = path.dirname(filePath);
21762
22477
  let r;
21763
22478
  while (r = CSS_IMPORT_RE.exec(cssText)) {
21764
22479
  const cssImportData = {
@@ -21772,7 +22487,7 @@ const getCssToEsmImports = (varNames, cssText, filePath, modeName) => {
21772
22487
  else if (isCssNodeModule(cssImportData.url)) {
21773
22488
  cssImportData.filePath = cssImportData.url.substring(1);
21774
22489
  cssImportData.isNodeModule = true;
21775
- } else if (path$1.isAbsolute(cssImportData.url)) cssImportData.filePath = normalizePath(cssImportData.url);
22490
+ } else if (path.isAbsolute(cssImportData.url)) cssImportData.filePath = normalizePath(cssImportData.url);
21776
22491
  else cssImportData.filePath = normalizePath(resolve$2(dir, cssImportData.url));
21777
22492
  cssImportData.varName = createCssVarName(cssImportData.filePath, modeName);
21778
22493
  if (varNames.has(cssImportData.varName)) cssImportData.varName += varNames.size;
@@ -21815,7 +22530,7 @@ const isLocalCssImport = (srcImport) => {
21815
22530
  * @returns an appropriate Css var name
21816
22531
  */
21817
22532
  const createCssVarName = (filePath, modeName) => {
21818
- let varName = path$1.basename(filePath);
22533
+ let varName = path.basename(filePath);
21819
22534
  if (modeName && modeName !== "$" && !varName.includes(modeName)) varName = modeName + "-" + varName;
21820
22535
  return createJsVarName(varName);
21821
22536
  };
@@ -22001,9 +22716,10 @@ const getTsConfigPath = async (config, sys) => {
22001
22716
  path: "",
22002
22717
  content: ""
22003
22718
  };
22004
- if (isString$1(config.tsconfig)) if (!isAbsolute$1(config.tsconfig)) tsconfig.path = join$2(config.rootDir, config.tsconfig);
22005
- else tsconfig.path = config.tsconfig;
22006
- 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");
22007
22723
  tsconfig.content = await sys.readFile(tsconfig.path);
22008
22724
  if (!isString$1(tsconfig.content)) {
22009
22725
  tsconfig.path = join$2(config.rootDir, "tsconfig.json");
@@ -22191,7 +22907,7 @@ const getWriteFilePathFromUrlPath = (manager, inputHref) => {
22191
22907
  const inputPathParts = inputPathname.split("/");
22192
22908
  const isPrerrenderRoot = basePathname === inputPathname;
22193
22909
  let fileName;
22194
- if (isPrerrenderRoot) fileName = path$1.basename(manager.outputTarget.indexHtml);
22910
+ if (isPrerrenderRoot) fileName = path.basename(manager.outputTarget.indexHtml);
22195
22911
  else fileName = "index.html";
22196
22912
  const pathParts = [];
22197
22913
  for (let i = 0; i < inputPathParts.length; i++) {
@@ -22248,13 +22964,15 @@ const addUrlToPendingQueue = (manager, queueUrl, fromUrl) => {
22248
22964
  };
22249
22965
  const drainPrerenderQueue = (results, manager) => {
22250
22966
  const nextUrl = manager.urlsPending.values().next();
22251
- if (!nextUrl.done) if (manager.urlsProcessing.size > manager.maxConcurrency) setTimeout(() => drainPrerenderQueue(results, manager));
22252
- else {
22253
- const url = nextUrl.value;
22254
- manager.urlsPending.delete(url);
22255
- manager.urlsProcessing.add(url);
22256
- prerenderUrl(results, manager, url);
22257
- 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
+ }
22258
22976
  }
22259
22977
  if (manager.urlsProcessing.size === 0 && manager.urlsPending.size === 0) {
22260
22978
  if (isFunction(manager.resolve)) {
@@ -22554,7 +23272,8 @@ const runPrerenderOutputTarget = async (workerCtx, results, diagnostics, config,
22554
23272
  if (debugDiagnostics.length > 0) config.logger.printDiagnostics(debugDiagnostics);
22555
23273
  }
22556
23274
  const duration = timeSpan.duration();
22557
- await generateRobotsTxt(manager, await generateSitemapXml(manager));
23275
+ const sitemapResults = await generateSitemapXml(manager);
23276
+ await generateRobotsTxt(manager, sitemapResults);
22558
23277
  const prerenderBuildErrors = prerenderDiagnostics.filter((d) => d.level === "error");
22559
23278
  const prerenderRuntimeErrors = prerenderDiagnostics.filter((d) => d.type === "runtime");
22560
23279
  if (prerenderBuildErrors.length > 0) {
@@ -22765,7 +23484,8 @@ const createSystem = (c) => {
22765
23484
  const itemStat = statSync(oldPath);
22766
23485
  if (!itemStat.error && !results.error) {
22767
23486
  if (itemStat.isFile) {
22768
- const createDirResults = createDirSync(dirname$1(newPath), { recursive: true });
23487
+ const newFileParentDir = dirname$1(newPath);
23488
+ const createDirResults = createDirSync(newFileParentDir, { recursive: true });
22769
23489
  const fileContent = items.get(oldPath).data;
22770
23490
  const writeResults = writeFileSync(newPath, fileContent);
22771
23491
  results.newDirs.push(...createDirResults.newDirs);
@@ -22787,7 +23507,10 @@ const createSystem = (c) => {
22787
23507
  isDirectory: true,
22788
23508
  isFile: false
22789
23509
  });
22790
- 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
+ }
22791
23514
  }
22792
23515
  }
22793
23516
  };
@@ -23019,7 +23742,7 @@ const createSystem = (c) => {
23019
23742
  isSymbolicLink,
23020
23743
  nextTick,
23021
23744
  normalizePath: normalize,
23022
- platformPath: path$1,
23745
+ platformPath: path,
23023
23746
  readDir,
23024
23747
  readDirSync,
23025
23748
  readFile,
@@ -23177,13 +23900,13 @@ const getTranspileConfigOpt = (value, validValues, defaultValue) => {
23177
23900
  if (validValues.has(value)) return value;
23178
23901
  return defaultValue;
23179
23902
  };
23180
- const VALID_EXPORT = new Set(["customelement", "module"]);
23181
- const VALID_METADATA = new Set(["compilerstatic", null]);
23182
- const VALID_MODULE = new Set(["cjs", "esm"]);
23183
- const VALID_PROXY = new Set(["defineproperty", null]);
23184
- const VALID_STYLE = new Set(["static"]);
23185
- const VALID_STYLE_IMPORT_DATA = new Set(["queryparams"]);
23186
- 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([
23187
23910
  "latest",
23188
23911
  "esnext",
23189
23912
  "es2020",
@@ -23343,8 +24066,10 @@ const transpile = async (code, opts = {}) => {
23343
24066
  patchTypescript(validatedConfig, null);
23344
24067
  transpileCode(validatedConfig, compileOpts, transformOpts, results);
23345
24068
  } else if (results.inputFileExtension === "d.ts") results.code = "";
23346
- else if (results.inputFileExtension === "css") await transpileCss(getTranspileCssConfig(opts, importData, results), results);
23347
- 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);
23348
24073
  } catch (e) {
23349
24074
  catchError(results.diagnostics, e);
23350
24075
  }
@@ -23368,8 +24093,10 @@ const transpileSync = (code, opts = {}) => {
23368
24093
  patchTypescript(validatedConfig, null);
23369
24094
  transpileCode(validatedConfig, compileOpts, transformOpts, results);
23370
24095
  } else if (results.inputFileExtension === "d.ts") results.code = "";
23371
- else if (results.inputFileExtension === "css") transpileCssSync(getTranspileCssConfig(opts, importData, results), results);
23372
- 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);
23373
24100
  } catch (e) {
23374
24101
  catchError(results.diagnostics, e);
23375
24102
  }