@stencil/core 5.0.0-beta.11 → 5.0.0-beta.12

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.
@@ -1693,6 +1693,18 @@ const createJsVarName = (fileName) => {
1693
1693
  }
1694
1694
  return fileName;
1695
1695
  };
1696
+ /**
1697
+ * Create a function that lowercases the first string parameter before passing it to the provided function
1698
+ * @param fn the function to pass the lowercased path to
1699
+ * @returns the result of the provided function
1700
+ */
1701
+ const lowerPathParam = (fn) => (p) => fn(p.toLowerCase());
1702
+ /**
1703
+ * Determine if a stringified file path is a TypeScript declaration file based on the extension at the end of the path.
1704
+ * @param p the path to evaluate
1705
+ * @returns `true` if the path ends in `.d.ts` (case-sensitive), `false` otherwise.
1706
+ */
1707
+ const isDtsFile = lowerPathParam((p) => p.endsWith(".d.ts") || p.endsWith(".d.mts") || p.endsWith(".d.cts"));
1696
1708
  function getTextDocs(docs) {
1697
1709
  if (docs == null) return "";
1698
1710
  return [escapeWithPattern(docs.text.replace(LINE_BREAK_REGEX, " "), /\*\//, "*\\/", true), ...docs.tags.filter((tag) => tag.name !== "internal").map((tag) => {
@@ -1832,7 +1844,7 @@ const validateComponentTag = (tag) => {
1832
1844
  };
1833
1845
  //#endregion
1834
1846
  //#region src/version.ts
1835
- const version = "5.0.0-beta.11";
1847
+ const version = "5.0.0-beta.12";
1836
1848
  //#endregion
1837
1849
  //#region src/compiler/events.ts
1838
1850
  const buildEvents = () => {
@@ -1895,6 +1907,7 @@ const resolve = (id, _opts, cb) => {
1895
1907
  };
1896
1908
  //#endregion
1897
1909
  //#region src/compiler/sys/resolve/resolve-utils.ts
1910
+ const isLocalModule = (p) => p.startsWith(".") || p.startsWith("/");
1898
1911
  const isNodeModulePath = (p) => normalizePath(p).split("/").includes("node_modules");
1899
1912
  const getModuleId = (orgImport) => {
1900
1913
  if (orgImport.startsWith("~")) orgImport = orgImport.substring(1);
@@ -4047,6 +4060,39 @@ const DEFAULT_BROWSER_TARGETS = [
4047
4060
  //#endregion
4048
4061
  //#region src/compiler/style/css-parser/parse-css.ts
4049
4062
  /**
4063
+ * Splits a selector list on top-level commas in a single pass: a comma only
4064
+ * splits when it's outside a quoted string and at paren depth 0, so commas in
4065
+ * `:is(:a,:has(:b))` or `[title="a,b"]` aren't treated as separators.
4066
+ * Backslash escapes (inside or outside a string) are skipped so they can't shift state,
4067
+ * so e.g. `[title="a\,b"]` is treated as a single selector.
4068
+ * @param selectors The selector list to split
4069
+ * @returns An array of selectors, with whitespace trimmed from each selector
4070
+ */
4071
+ const splitSelectorList = (selectors) => {
4072
+ const parts = [];
4073
+ let depth = 0;
4074
+ let quote = null;
4075
+ let start = 0;
4076
+ for (let i = 0; i < selectors.length; i++) {
4077
+ const ch = selectors[i];
4078
+ if (quote) {
4079
+ if (ch === "\\") i++;
4080
+ else if (ch === quote) quote = null;
4081
+ continue;
4082
+ }
4083
+ if (ch === "\"" || ch === "'") quote = ch;
4084
+ else if (ch === "\\") i++;
4085
+ else if (ch === "(") depth++;
4086
+ else if (ch === ")") depth = Math.max(0, depth - 1);
4087
+ else if (ch === "," && depth === 0) {
4088
+ parts.push(selectors.slice(start, i));
4089
+ start = i + 1;
4090
+ }
4091
+ }
4092
+ parts.push(selectors.slice(start));
4093
+ return parts.map((s) => s.trim());
4094
+ };
4095
+ /**
4050
4096
  * Parses CSS string input into an AST representation.
4051
4097
  * Used for minification, finding & resolving URLs and during SSR / prerendering, removing unused selectors.
4052
4098
  *
@@ -4171,11 +4217,8 @@ const parseCss = (css, filePath) => {
4171
4217
  const selector = () => {
4172
4218
  const m = match(/^([^{]+)/);
4173
4219
  if (!m) return null;
4174
- return trim(m[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, "").replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(str) {
4175
- return str.replace(/,/g, "‌");
4176
- }).split(/\s*(?![^(]*\)),\s*/).map(function(s) {
4177
- return s.replace(/\u200C/g, ",");
4178
- });
4220
+ const cleaned = trim(m[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, "");
4221
+ return splitSelectorList(cleaned);
4179
4222
  };
4180
4223
  const declaration = () => {
4181
4224
  const pos = position();
@@ -13956,25 +13999,161 @@ function matchesNamedDeclaration(name) {
13956
13999
  };
13957
14000
  }
13958
14001
  /**
13959
- * Finds a re-export of `className` in `sourceFile` - `export { X } from './y'` or
13960
- * `export { X as Y } from './y'` - as used by barrel entry points (e.g. `@stencil/core`'s own
13961
- * public `index.d.mts`, which re-exports its runtime API from `./declarations/stencil-public-runtime`
13962
- * rather than declaring it directly).
14002
+ * Finds a re-export of `className` in `sourceFile`: `export { X } from './y'`, or the
14003
+ * bundler-split shape `import { X as name } from './y'; export { name };` (no `from` clause).
13963
14004
  * @param sourceFile the (barrel) source file to scan
13964
14005
  * @param className the exported name to look for
13965
- * @returns the module specifier and the name to look for in that module (the local name, before
13966
- * any `as` aliasing), or `undefined` if no matching re-export is found
14006
+ * @returns the module specifier and name to look for there (before any `as` aliasing), or
14007
+ * `undefined` if not found
13967
14008
  */
13968
14009
  function findReExport(sourceFile, className) {
13969
14010
  for (const stmt of sourceFile.statements) {
13970
- if (!ts$1.isExportDeclaration(stmt) || !stmt.moduleSpecifier || !ts$1.isStringLiteral(stmt.moduleSpecifier) || !stmt.exportClause || !ts$1.isNamedExports(stmt.exportClause)) continue;
13971
- for (const element of stmt.exportClause.elements) if (element.name.text === className) return {
14011
+ if (!ts$1.isExportDeclaration(stmt) || !stmt.exportClause || !ts$1.isNamedExports(stmt.exportClause)) continue;
14012
+ const element = stmt.exportClause.elements.find((el) => el.name.text === className);
14013
+ if (!element) continue;
14014
+ if (stmt.moduleSpecifier && ts$1.isStringLiteral(stmt.moduleSpecifier)) return {
13972
14015
  moduleSpecifier: stmt.moduleSpecifier.text,
13973
14016
  localName: element.propertyName?.text ?? element.name.text
13974
14017
  };
14018
+ const importOrigin = findImportOrigin(sourceFile, element.propertyName?.text ?? element.name.text);
14019
+ if (importOrigin) return importOrigin;
14020
+ }
14021
+ }
14022
+ /**
14023
+ * Finds `name`'s import in `sourceFile` and returns its module and origin name (before any `as`
14024
+ * aliasing; `'default'` for a default import).
14025
+ * @param sourceFile the source file to scan for a matching import
14026
+ * @param name the local (post-aliasing) name an import bound
14027
+ * @returns the import's module specifier and origin name, or `undefined` if `name` isn't imported
14028
+ */
14029
+ function findImportOrigin(sourceFile, name) {
14030
+ for (const stmt of sourceFile.statements) {
14031
+ if (!ts$1.isImportDeclaration(stmt) || !stmt.importClause || !ts$1.isStringLiteral(stmt.moduleSpecifier)) continue;
14032
+ const moduleSpecifier = stmt.moduleSpecifier.text;
14033
+ if (stmt.importClause.name?.text === name) return {
14034
+ moduleSpecifier,
14035
+ localName: "default"
14036
+ };
14037
+ const bindings = stmt.importClause.namedBindings;
14038
+ if (!bindings || !ts$1.isNamedImports(bindings)) continue;
14039
+ const element = bindings.elements.find((el) => el.name.text === name);
14040
+ if (element) return {
14041
+ moduleSpecifier,
14042
+ localName: element.propertyName?.text ?? element.name.text
14043
+ };
13975
14044
  }
13976
14045
  }
13977
14046
  /**
14047
+ * Finds `name` as a top-level declaration in `sf` (see `matchesNamedDeclaration`), following a
14048
+ * same-file export alias if `name` is only ever the public side of a local rename
14049
+ * (`export { RealName as name }`, no `from` clause).
14050
+ * @param sf the source file to search
14051
+ * @param name the declaration name to look for, which may only exist as an export alias
14052
+ * @returns the matched statement, or `undefined`
14053
+ */
14054
+ function findStatementByName(sf, name) {
14055
+ const direct = sf.statements.find(matchesNamedDeclaration(name));
14056
+ if (direct) return direct;
14057
+ for (const stmt of sf.statements) {
14058
+ if (!ts$1.isExportDeclaration(stmt) || stmt.moduleSpecifier || !stmt.exportClause || !ts$1.isNamedExports(stmt.exportClause)) continue;
14059
+ const aliasedName = stmt.exportClause.elements.find((el) => el.name.text === name)?.propertyName?.text;
14060
+ if (aliasedName && aliasedName !== name) return sf.statements.find(matchesNamedDeclaration(aliasedName));
14061
+ }
14062
+ }
14063
+ /**
14064
+ * Picks the runtime target out of a `package.json` `exports` condition entry - prefers `import`
14065
+ * over `require`/`node`/`default`, recursing into nested condition objects.
14066
+ * @param entry an `exports` map value: a path string, or nested conditions
14067
+ * @returns the resolved relative path, or `undefined` if no usable condition was found
14068
+ */
14069
+ function pickJsCondition(entry) {
14070
+ if (typeof entry === "string") return entry;
14071
+ if (typeof entry !== "object" || entry === null) return;
14072
+ const conditions = entry;
14073
+ for (const key of [
14074
+ "import",
14075
+ "require",
14076
+ "node",
14077
+ "default"
14078
+ ]) if (key in conditions) {
14079
+ const picked = pickJsCondition(conditions[key]);
14080
+ if (picked) return picked;
14081
+ }
14082
+ }
14083
+ /**
14084
+ * Reads and parses `filePath` as JS, with parent nodes set - unlike `tsGetSourceFile`, which
14085
+ * never triggers binding, so `.parent` stays unset and `node.getSourceFile()` returns `undefined`.
14086
+ * @param config the current Stencil validated config
14087
+ * @param filePath the absolute path of the JS file to read and parse
14088
+ * @returns the parsed source file, or `undefined` if it couldn't be read
14089
+ */
14090
+ function readJsSourceFile(config, filePath) {
14091
+ try {
14092
+ const text = config.sys.readFileSync(filePath);
14093
+ if (typeof text !== "string") return;
14094
+ return ts$1.createSourceFile(filePath, text, ts$1.ScriptTarget.ESNext, true, ts$1.ScriptKind.JS);
14095
+ } catch {
14096
+ return;
14097
+ }
14098
+ }
14099
+ /**
14100
+ * Resolves the runtime JS entry for a bare (non-relative) module specifier by reading its
14101
+ * package's own `package.json` `exports` map, instead of `tsResolveModuleName` - which always
14102
+ * resolves to the package's `types` entry, an ambient signature with no body a mixin factory's
14103
+ * class can never be found inside.
14104
+ * @param config the current Stencil validated config
14105
+ * @param compilerCtx the current compiler context
14106
+ * @param moduleSpecifier the bare package specifier to resolve
14107
+ * @param containingFile the file the specifier was imported from
14108
+ * @returns the resolved JS source file, or `undefined` if it couldn't be resolved this way
14109
+ */
14110
+ function resolveModuleJsEntry(config, compilerCtx, moduleSpecifier, containingFile) {
14111
+ if (isLocalModule(moduleSpecifier)) return;
14112
+ const pkgJsonPath = tsResolveModuleNamePackageJsonPath(config, compilerCtx, moduleSpecifier, containingFile);
14113
+ if (!pkgJsonPath) return;
14114
+ let pkgJson;
14115
+ try {
14116
+ pkgJson = JSON.parse(config.sys.readFileSync(pkgJsonPath));
14117
+ } catch {
14118
+ return;
14119
+ }
14120
+ const pkgName = pkgJson.name;
14121
+ if (!pkgName || !moduleSpecifier.startsWith(pkgName) || !pkgJson.exports) return;
14122
+ const subpath = moduleSpecifier === pkgName ? "." : `.${moduleSpecifier.slice(pkgName.length)}`;
14123
+ const exportsMap = pkgJson.exports;
14124
+ const conditionEntry = typeof exportsMap === "string" ? subpath === "." ? exportsMap : void 0 : exportsMap[subpath] ?? (subpath === "." ? exportsMap : void 0);
14125
+ const target = conditionEntry && pickJsCondition(conditionEntry);
14126
+ if (!target) return;
14127
+ return readJsSourceFile(config, normalizePath(join$1(dirname(pkgJsonPath), target)));
14128
+ }
14129
+ /**
14130
+ * Finds `className`'s class inside a resolved JS entry (see `resolveModuleJsEntry`), following
14131
+ * re-export hops the same way `resolveAndProcessExtendedClass` walks a `.d.ts`/`.ts` source.
14132
+ * @param config the current Stencil validated config
14133
+ * @param compilerCtx the current compiler context
14134
+ * @param source the JS source file to search
14135
+ * @param className the class (or mixin factory) name to look for
14136
+ * @param hopsRemaining re-export hops still allowed before giving up
14137
+ * @returns the found class and the source file it's declared in, or `undefined`
14138
+ */
14139
+ function findClassInJsModule(config, compilerCtx, source, className, hopsRemaining = 3) {
14140
+ const matchedStatement = findStatementByName(source, className);
14141
+ if (matchedStatement) {
14142
+ const classNode = ts$1.isClassDeclaration(matchedStatement) ? matchedStatement : findClassWalk(matchedStatement);
14143
+ return classNode && {
14144
+ classNode,
14145
+ sourceFile: source
14146
+ };
14147
+ }
14148
+ if (hopsRemaining <= 0) return;
14149
+ const reExport = findReExport(source, className);
14150
+ if (!reExport) return;
14151
+ const resolvedFileName = tsResolveModuleName(config, compilerCtx, reExport.moduleSpecifier, source.fileName)?.resolvedModule?.resolvedFileName;
14152
+ const nextSource = resolvedFileName && readJsSourceFile(config, resolvedFileName);
14153
+ if (!nextSource) return;
14154
+ return findClassInJsModule(config, compilerCtx, nextSource, reExport.localName, hopsRemaining - 1);
14155
+ }
14156
+ /**
13978
14157
  * Filters `dedupeMembers` down to entries not already present in `staticMembers`
13979
14158
  * (by name, or `methodName` for change handlers) - used so an extending
13980
14159
  * class's own members win over inherited ones.
@@ -14080,9 +14259,11 @@ function convertDiskSourceFileDecorators(sourceFile, config, target = ts$1.Scrip
14080
14259
  * @param ogModule the original module file of the class declaration
14081
14260
  * @param targetScriptTarget the script target to convert decorators with, if needed
14082
14261
  * @param barrelHopsRemaining re-export hops still allowed before giving up
14262
+ * @param originalModuleSpecifier the specifier this lookup started from, before any barrel hops
14263
+ * @param originalContainingFile the file `originalModuleSpecifier` was imported from
14083
14264
  * @returns the found class declaration, or `undefined`
14084
14265
  */
14085
- function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, currentSource, moduleSpecifier, className, dependentClasses, typeChecker, ogModule, targetScriptTarget = ts$1.ScriptTarget.ESNext, barrelHopsRemaining = 1) {
14266
+ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, currentSource, moduleSpecifier, className, dependentClasses, typeChecker, ogModule, targetScriptTarget = ts$1.ScriptTarget.ESNext, barrelHopsRemaining = 1, originalModuleSpecifier = moduleSpecifier, originalContainingFile = currentSource.fileName) {
14086
14267
  let keepLooking = true;
14087
14268
  const foundFile = tsResolveModuleName(buildCtx.config, compilerCtx, moduleSpecifier, currentSource.fileName);
14088
14269
  if (!foundFile?.resolvedModule || !className) return;
@@ -14098,10 +14279,10 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
14098
14279
  }
14099
14280
  foundSource = convertDiskSourceFileDecorators(foundSource, buildCtx.config, targetScriptTarget);
14100
14281
  }
14101
- const matchedStatement = foundSource.statements.find(matchesNamedDeclaration(className));
14282
+ const matchedStatement = findStatementByName(foundSource, className);
14102
14283
  if (!matchedStatement) {
14103
14284
  const reExport = barrelHopsRemaining > 0 ? findReExport(foundSource, className) : void 0;
14104
- if (reExport) return resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, foundSource, reExport.moduleSpecifier, reExport.localName, dependentClasses, typeChecker, ogModule, targetScriptTarget, barrelHopsRemaining - 1);
14285
+ if (reExport) return resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, foundSource, reExport.moduleSpecifier, reExport.localName, dependentClasses, typeChecker, ogModule, targetScriptTarget, barrelHopsRemaining - 1, originalModuleSpecifier, originalContainingFile);
14105
14286
  const err = buildWarn(buildCtx.diagnostics);
14106
14287
  err.messageText = `Unable to find "${className}" in the imported module "${moduleSpecifier}".
14107
14288
  Please import class / mixin-factory declarations directly and not via barrel files.`;
@@ -14109,16 +14290,25 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
14109
14290
  return;
14110
14291
  }
14111
14292
  let foundClassDeclaration = matchedStatement ? ts$1.isClassDeclaration(matchedStatement) ? matchedStatement : void 0 : void 0;
14293
+ let foundClassSource = foundSource;
14112
14294
  if (!foundClassDeclaration && matchedStatement) {
14113
14295
  foundClassDeclaration = findClassWalk(matchedStatement);
14114
14296
  keepLooking = false;
14297
+ if (!foundClassDeclaration && isDtsFile(foundSource.fileName) && !isLocalModule(originalModuleSpecifier)) {
14298
+ const jsSource = resolveModuleJsEntry(buildCtx.config, compilerCtx, originalModuleSpecifier, originalContainingFile);
14299
+ const foundInJs = jsSource && findClassInJsModule(buildCtx.config, compilerCtx, jsSource, className);
14300
+ if (foundInJs) {
14301
+ foundClassDeclaration = foundInJs.classNode;
14302
+ foundClassSource = foundInJs.sourceFile;
14303
+ }
14304
+ }
14115
14305
  if (!foundClassDeclaration) warnMixinFactoryClassNotFound(buildCtx, className, classDeclaration);
14116
14306
  }
14117
14307
  if (foundClassDeclaration && !dependentClasses.some((dc) => dc.classNode === foundClassDeclaration)) {
14118
14308
  dependentClasses.push({
14119
14309
  classNode: foundClassDeclaration,
14120
- sourceFile: foundSource,
14121
- fileName: foundFile.resolvedModule.resolvedFileName
14310
+ sourceFile: foundClassSource,
14311
+ fileName: foundClassSource.fileName
14122
14312
  });
14123
14313
  if (keepLooking) buildExtendsTree(compilerCtx, foundClassDeclaration, dependentClasses, typeChecker, buildCtx, ogModule);
14124
14314
  }
@@ -14525,19 +14715,6 @@ function getExtendsClassNames(node) {
14525
14715
  if (ts$1.isCallExpression(expr) && expr.expression.getText() === "Mixin") return expr.arguments.filter(ts$1.isIdentifier).map((id) => id.text);
14526
14716
  return [];
14527
14717
  }
14528
- function findImportSpecifier(sf, localName) {
14529
- for (const stmt of sf.statements) {
14530
- if (!ts$1.isImportDeclaration(stmt) || !ts$1.isStringLiteral(stmt.moduleSpecifier)) continue;
14531
- const clause = stmt.importClause;
14532
- if (!clause) continue;
14533
- if (clause.name?.text === localName) return stmt.moduleSpecifier.text;
14534
- const bindings = clause.namedBindings;
14535
- if (bindings && ts$1.isNamedImports(bindings)) {
14536
- for (const el of bindings.elements) if (el.name.text === localName) return stmt.moduleSpecifier.text;
14537
- }
14538
- }
14539
- return null;
14540
- }
14541
14718
  /**
14542
14719
  * A single-file mini-program (see `convertInMemorySourceDecorators`) can
14543
14720
  * never load an imported module's own `SourceFile`, so a type that's
@@ -14561,7 +14738,7 @@ function reclassifyGlobalTypeReferences(members, declaringSf, declaringPath, res
14561
14738
  if (!references) return;
14562
14739
  Object.entries(references).forEach(([typeName, reference]) => {
14563
14740
  if (reference.location !== "global") return;
14564
- const specifier = findImportSpecifier(declaringSf, typeName);
14741
+ const specifier = findImportOrigin(declaringSf, typeName)?.moduleSpecifier;
14565
14742
  if (!specifier) return;
14566
14743
  const resolved = resolveImport(specifier, declaringPath);
14567
14744
  reference.location = "import";
@@ -14584,7 +14761,7 @@ function reclassifyGlobalTypeReferences(members, declaringSf, declaringPath, res
14584
14761
  * differ from `sf`/`path` if resolved through a re-export), or `undefined`
14585
14762
  */
14586
14763
  function findDeclarationOrReExport(sf, path, name, resolveImport) {
14587
- const direct = sf.statements.find(matchesNamedDeclaration(name));
14764
+ const direct = findStatementByName(sf, name);
14588
14765
  if (direct) return {
14589
14766
  statement: direct,
14590
14767
  sourceFile: sf,
@@ -14597,7 +14774,7 @@ function findDeclarationOrReExport(sf, path, name, resolveImport) {
14597
14774
  const { code, path: resolvedPath } = resolved;
14598
14775
  const isTs = resolvedPath.endsWith(".tsx") || resolvedPath.endsWith(".ts");
14599
14776
  const reExportSf = ts$1.createSourceFile(resolvedPath, code, ts$1.ScriptTarget.ESNext, true, isTs ? ts$1.ScriptKind.TSX : ts$1.ScriptKind.JS);
14600
- const statement = reExportSf.statements.find(matchesNamedDeclaration(reExport.localName));
14777
+ const statement = findStatementByName(reExportSf, reExport.localName);
14601
14778
  if (!statement) return void 0;
14602
14779
  return {
14603
14780
  statement,
@@ -14634,7 +14811,7 @@ function resolveAncestors(classNode, sf, path, resolveImport, visited, ancestors
14634
14811
  let foundSf = sf;
14635
14812
  let foundPath = path;
14636
14813
  let keepLooking = true;
14637
- const sameFileStatement = sf.statements.find(matchesNamedDeclaration(parentName));
14814
+ const sameFileStatement = findStatementByName(sf, parentName);
14638
14815
  if (sameFileStatement) {
14639
14816
  if (ts$1.isClassDeclaration(sameFileStatement)) foundClass = sameFileStatement;
14640
14817
  else {
@@ -14643,7 +14820,7 @@ function resolveAncestors(classNode, sf, path, resolveImport, visited, ancestors
14643
14820
  if (!foundClass) warnMixinFactoryClassNotFound(buildCtx, parentName, rootClassDeclaration);
14644
14821
  }
14645
14822
  } else {
14646
- const specifier = findImportSpecifier(sf, parentName);
14823
+ const specifier = findImportOrigin(sf, parentName)?.moduleSpecifier;
14647
14824
  if (!specifier) continue;
14648
14825
  const resolved = resolveImport(specifier, path);
14649
14826
  if (!resolved) continue;
@@ -1,3 +1,3 @@
1
- import { _ as buildId, a as createPrerenderer, b as versions, c as createWorkerContext, d as nodeRequire, f as optimizeCss, g as getScopeId, h as cmpMetaToDocsComponent, i as createSystem, l as createWorkerMessageHandler, m as generateManifest, n as transpile, o as loadConfig, p as validateConfig, r as transpileSync, s as createCompiler, t as ts, u as optimizeJs, v as vermoji, x as scopeCss, y as version } from "../compiler-2EypBn_Y.mjs";
1
+ import { _ as buildId, a as createPrerenderer, b as versions, c as createWorkerContext, d as nodeRequire, f as optimizeCss, g as getScopeId, h as cmpMetaToDocsComponent, i as createSystem, l as createWorkerMessageHandler, m as generateManifest, n as transpile, o as loadConfig, p as validateConfig, r as transpileSync, s as createCompiler, t as ts, u as optimizeJs, v as vermoji, x as scopeCss, y as version } from "../compiler-BjKDj129.mjs";
2
2
  import { a as LOG_LEVELS, i as CustomElementsExportBehaviorOptions } from "../node-HKfDhPR3.mjs";
3
3
  export { CustomElementsExportBehaviorOptions, LOG_LEVELS, buildId, cmpMetaToDocsComponent, createCompiler, createPrerenderer, createSystem, createWorkerContext, createWorkerMessageHandler, generateManifest, getScopeId, loadConfig, nodeRequire, optimizeCss, optimizeJs, scopeCss, transpile, transpileSync, ts, validateConfig, vermoji, version, versions };
@@ -461,9 +461,9 @@ const scopeCss = (cssText, scopeId, commentOriginalSelector) => {
461
461
  };
462
462
  //#endregion
463
463
  //#region src/version.ts
464
- const version = "5.0.0-beta.11";
465
- const buildId = "1789429964";
466
- const vermoji = "🍦";
464
+ const version = "5.0.0-beta.12";
465
+ const buildId = "1789547794";
466
+ const vermoji = "🏇";
467
467
  /**
468
468
  * Get the installed version of a tool/dependency.
469
469
  * Handles packages with exports maps that point to subdirectories.
@@ -2854,6 +2854,7 @@ const setPackageVersionByContent = (pkgVersions, pkgContent) => {
2854
2854
  if (pkg.name && pkg.version) setPackageVersion(pkgVersions, pkg.name, pkg.version);
2855
2855
  } catch {}
2856
2856
  };
2857
+ const isLocalModule = (p) => p.startsWith(".") || p.startsWith("/");
2857
2858
  const isNodeModulePath = (p) => normalizePath(p).split("/").includes("node_modules");
2858
2859
  const getModuleId = (orgImport) => {
2859
2860
  if (orgImport.startsWith("~")) orgImport = orgImport.substring(1);
@@ -15691,25 +15692,161 @@ function matchesNamedDeclaration(name) {
15691
15692
  };
15692
15693
  }
15693
15694
  /**
15694
- * Finds a re-export of `className` in `sourceFile` - `export { X } from './y'` or
15695
- * `export { X as Y } from './y'` - as used by barrel entry points (e.g. `@stencil/core`'s own
15696
- * public `index.d.mts`, which re-exports its runtime API from `./declarations/stencil-public-runtime`
15697
- * rather than declaring it directly).
15695
+ * Finds a re-export of `className` in `sourceFile`: `export { X } from './y'`, or the
15696
+ * bundler-split shape `import { X as name } from './y'; export { name };` (no `from` clause).
15698
15697
  * @param sourceFile the (barrel) source file to scan
15699
15698
  * @param className the exported name to look for
15700
- * @returns the module specifier and the name to look for in that module (the local name, before
15701
- * any `as` aliasing), or `undefined` if no matching re-export is found
15699
+ * @returns the module specifier and name to look for there (before any `as` aliasing), or
15700
+ * `undefined` if not found
15702
15701
  */
15703
15702
  function findReExport(sourceFile, className) {
15704
15703
  for (const stmt of sourceFile.statements) {
15705
- if (!ts.isExportDeclaration(stmt) || !stmt.moduleSpecifier || !ts.isStringLiteral(stmt.moduleSpecifier) || !stmt.exportClause || !ts.isNamedExports(stmt.exportClause)) continue;
15706
- for (const element of stmt.exportClause.elements) if (element.name.text === className) return {
15704
+ if (!ts.isExportDeclaration(stmt) || !stmt.exportClause || !ts.isNamedExports(stmt.exportClause)) continue;
15705
+ const element = stmt.exportClause.elements.find((el) => el.name.text === className);
15706
+ if (!element) continue;
15707
+ if (stmt.moduleSpecifier && ts.isStringLiteral(stmt.moduleSpecifier)) return {
15707
15708
  moduleSpecifier: stmt.moduleSpecifier.text,
15708
15709
  localName: element.propertyName?.text ?? element.name.text
15709
15710
  };
15711
+ const importOrigin = findImportOrigin(sourceFile, element.propertyName?.text ?? element.name.text);
15712
+ if (importOrigin) return importOrigin;
15710
15713
  }
15711
15714
  }
15712
15715
  /**
15716
+ * Finds `name`'s import in `sourceFile` and returns its module and origin name (before any `as`
15717
+ * aliasing; `'default'` for a default import).
15718
+ * @param sourceFile the source file to scan for a matching import
15719
+ * @param name the local (post-aliasing) name an import bound
15720
+ * @returns the import's module specifier and origin name, or `undefined` if `name` isn't imported
15721
+ */
15722
+ function findImportOrigin(sourceFile, name) {
15723
+ for (const stmt of sourceFile.statements) {
15724
+ if (!ts.isImportDeclaration(stmt) || !stmt.importClause || !ts.isStringLiteral(stmt.moduleSpecifier)) continue;
15725
+ const moduleSpecifier = stmt.moduleSpecifier.text;
15726
+ if (stmt.importClause.name?.text === name) return {
15727
+ moduleSpecifier,
15728
+ localName: "default"
15729
+ };
15730
+ const bindings = stmt.importClause.namedBindings;
15731
+ if (!bindings || !ts.isNamedImports(bindings)) continue;
15732
+ const element = bindings.elements.find((el) => el.name.text === name);
15733
+ if (element) return {
15734
+ moduleSpecifier,
15735
+ localName: element.propertyName?.text ?? element.name.text
15736
+ };
15737
+ }
15738
+ }
15739
+ /**
15740
+ * Finds `name` as a top-level declaration in `sf` (see `matchesNamedDeclaration`), following a
15741
+ * same-file export alias if `name` is only ever the public side of a local rename
15742
+ * (`export { RealName as name }`, no `from` clause).
15743
+ * @param sf the source file to search
15744
+ * @param name the declaration name to look for, which may only exist as an export alias
15745
+ * @returns the matched statement, or `undefined`
15746
+ */
15747
+ function findStatementByName(sf, name) {
15748
+ const direct = sf.statements.find(matchesNamedDeclaration(name));
15749
+ if (direct) return direct;
15750
+ for (const stmt of sf.statements) {
15751
+ if (!ts.isExportDeclaration(stmt) || stmt.moduleSpecifier || !stmt.exportClause || !ts.isNamedExports(stmt.exportClause)) continue;
15752
+ const aliasedName = stmt.exportClause.elements.find((el) => el.name.text === name)?.propertyName?.text;
15753
+ if (aliasedName && aliasedName !== name) return sf.statements.find(matchesNamedDeclaration(aliasedName));
15754
+ }
15755
+ }
15756
+ /**
15757
+ * Picks the runtime target out of a `package.json` `exports` condition entry - prefers `import`
15758
+ * over `require`/`node`/`default`, recursing into nested condition objects.
15759
+ * @param entry an `exports` map value: a path string, or nested conditions
15760
+ * @returns the resolved relative path, or `undefined` if no usable condition was found
15761
+ */
15762
+ function pickJsCondition(entry) {
15763
+ if (typeof entry === "string") return entry;
15764
+ if (typeof entry !== "object" || entry === null) return;
15765
+ const conditions = entry;
15766
+ for (const key of [
15767
+ "import",
15768
+ "require",
15769
+ "node",
15770
+ "default"
15771
+ ]) if (key in conditions) {
15772
+ const picked = pickJsCondition(conditions[key]);
15773
+ if (picked) return picked;
15774
+ }
15775
+ }
15776
+ /**
15777
+ * Reads and parses `filePath` as JS, with parent nodes set - unlike `tsGetSourceFile`, which
15778
+ * never triggers binding, so `.parent` stays unset and `node.getSourceFile()` returns `undefined`.
15779
+ * @param config the current Stencil validated config
15780
+ * @param filePath the absolute path of the JS file to read and parse
15781
+ * @returns the parsed source file, or `undefined` if it couldn't be read
15782
+ */
15783
+ function readJsSourceFile(config, filePath) {
15784
+ try {
15785
+ const text = config.sys.readFileSync(filePath);
15786
+ if (typeof text !== "string") return;
15787
+ return ts.createSourceFile(filePath, text, ts.ScriptTarget.ESNext, true, ts.ScriptKind.JS);
15788
+ } catch {
15789
+ return;
15790
+ }
15791
+ }
15792
+ /**
15793
+ * Resolves the runtime JS entry for a bare (non-relative) module specifier by reading its
15794
+ * package's own `package.json` `exports` map, instead of `tsResolveModuleName` - which always
15795
+ * resolves to the package's `types` entry, an ambient signature with no body a mixin factory's
15796
+ * class can never be found inside.
15797
+ * @param config the current Stencil validated config
15798
+ * @param compilerCtx the current compiler context
15799
+ * @param moduleSpecifier the bare package specifier to resolve
15800
+ * @param containingFile the file the specifier was imported from
15801
+ * @returns the resolved JS source file, or `undefined` if it couldn't be resolved this way
15802
+ */
15803
+ function resolveModuleJsEntry(config, compilerCtx, moduleSpecifier, containingFile) {
15804
+ if (isLocalModule(moduleSpecifier)) return;
15805
+ const pkgJsonPath = tsResolveModuleNamePackageJsonPath(config, compilerCtx, moduleSpecifier, containingFile);
15806
+ if (!pkgJsonPath) return;
15807
+ let pkgJson;
15808
+ try {
15809
+ pkgJson = JSON.parse(config.sys.readFileSync(pkgJsonPath));
15810
+ } catch {
15811
+ return;
15812
+ }
15813
+ const pkgName = pkgJson.name;
15814
+ if (!pkgName || !moduleSpecifier.startsWith(pkgName) || !pkgJson.exports) return;
15815
+ const subpath = moduleSpecifier === pkgName ? "." : `.${moduleSpecifier.slice(pkgName.length)}`;
15816
+ const exportsMap = pkgJson.exports;
15817
+ const conditionEntry = typeof exportsMap === "string" ? subpath === "." ? exportsMap : void 0 : exportsMap[subpath] ?? (subpath === "." ? exportsMap : void 0);
15818
+ const target = conditionEntry && pickJsCondition(conditionEntry);
15819
+ if (!target) return;
15820
+ return readJsSourceFile(config, normalizePath(join$2(dirname$1(pkgJsonPath), target)));
15821
+ }
15822
+ /**
15823
+ * Finds `className`'s class inside a resolved JS entry (see `resolveModuleJsEntry`), following
15824
+ * re-export hops the same way `resolveAndProcessExtendedClass` walks a `.d.ts`/`.ts` source.
15825
+ * @param config the current Stencil validated config
15826
+ * @param compilerCtx the current compiler context
15827
+ * @param source the JS source file to search
15828
+ * @param className the class (or mixin factory) name to look for
15829
+ * @param hopsRemaining re-export hops still allowed before giving up
15830
+ * @returns the found class and the source file it's declared in, or `undefined`
15831
+ */
15832
+ function findClassInJsModule(config, compilerCtx, source, className, hopsRemaining = 3) {
15833
+ const matchedStatement = findStatementByName(source, className);
15834
+ if (matchedStatement) {
15835
+ const classNode = ts.isClassDeclaration(matchedStatement) ? matchedStatement : findClassWalk(matchedStatement);
15836
+ return classNode && {
15837
+ classNode,
15838
+ sourceFile: source
15839
+ };
15840
+ }
15841
+ if (hopsRemaining <= 0) return;
15842
+ const reExport = findReExport(source, className);
15843
+ if (!reExport) return;
15844
+ const resolvedFileName = tsResolveModuleName(config, compilerCtx, reExport.moduleSpecifier, source.fileName)?.resolvedModule?.resolvedFileName;
15845
+ const nextSource = resolvedFileName && readJsSourceFile(config, resolvedFileName);
15846
+ if (!nextSource) return;
15847
+ return findClassInJsModule(config, compilerCtx, nextSource, reExport.localName, hopsRemaining - 1);
15848
+ }
15849
+ /**
15713
15850
  * Filters `dedupeMembers` down to entries not already present in `staticMembers`
15714
15851
  * (by name, or `methodName` for change handlers) - used so an extending
15715
15852
  * class's own members win over inherited ones.
@@ -15815,9 +15952,11 @@ function convertDiskSourceFileDecorators(sourceFile, config, target = ts.ScriptT
15815
15952
  * @param ogModule the original module file of the class declaration
15816
15953
  * @param targetScriptTarget the script target to convert decorators with, if needed
15817
15954
  * @param barrelHopsRemaining re-export hops still allowed before giving up
15955
+ * @param originalModuleSpecifier the specifier this lookup started from, before any barrel hops
15956
+ * @param originalContainingFile the file `originalModuleSpecifier` was imported from
15818
15957
  * @returns the found class declaration, or `undefined`
15819
15958
  */
15820
- function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, currentSource, moduleSpecifier, className, dependentClasses, typeChecker, ogModule, targetScriptTarget = ts.ScriptTarget.ESNext, barrelHopsRemaining = 1) {
15959
+ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, currentSource, moduleSpecifier, className, dependentClasses, typeChecker, ogModule, targetScriptTarget = ts.ScriptTarget.ESNext, barrelHopsRemaining = 1, originalModuleSpecifier = moduleSpecifier, originalContainingFile = currentSource.fileName) {
15821
15960
  let keepLooking = true;
15822
15961
  const foundFile = tsResolveModuleName(buildCtx.config, compilerCtx, moduleSpecifier, currentSource.fileName);
15823
15962
  if (!foundFile?.resolvedModule || !className) return;
@@ -15833,10 +15972,10 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
15833
15972
  }
15834
15973
  foundSource = convertDiskSourceFileDecorators(foundSource, buildCtx.config, targetScriptTarget);
15835
15974
  }
15836
- const matchedStatement = foundSource.statements.find(matchesNamedDeclaration(className));
15975
+ const matchedStatement = findStatementByName(foundSource, className);
15837
15976
  if (!matchedStatement) {
15838
15977
  const reExport = barrelHopsRemaining > 0 ? findReExport(foundSource, className) : void 0;
15839
- if (reExport) return resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, foundSource, reExport.moduleSpecifier, reExport.localName, dependentClasses, typeChecker, ogModule, targetScriptTarget, barrelHopsRemaining - 1);
15978
+ if (reExport) return resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, foundSource, reExport.moduleSpecifier, reExport.localName, dependentClasses, typeChecker, ogModule, targetScriptTarget, barrelHopsRemaining - 1, originalModuleSpecifier, originalContainingFile);
15840
15979
  const err = buildWarn(buildCtx.diagnostics);
15841
15980
  err.messageText = `Unable to find "${className}" in the imported module "${moduleSpecifier}".
15842
15981
  Please import class / mixin-factory declarations directly and not via barrel files.`;
@@ -15844,16 +15983,25 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
15844
15983
  return;
15845
15984
  }
15846
15985
  let foundClassDeclaration = matchedStatement ? ts.isClassDeclaration(matchedStatement) ? matchedStatement : void 0 : void 0;
15986
+ let foundClassSource = foundSource;
15847
15987
  if (!foundClassDeclaration && matchedStatement) {
15848
15988
  foundClassDeclaration = findClassWalk(matchedStatement);
15849
15989
  keepLooking = false;
15990
+ if (!foundClassDeclaration && isDtsFile(foundSource.fileName) && !isLocalModule(originalModuleSpecifier)) {
15991
+ const jsSource = resolveModuleJsEntry(buildCtx.config, compilerCtx, originalModuleSpecifier, originalContainingFile);
15992
+ const foundInJs = jsSource && findClassInJsModule(buildCtx.config, compilerCtx, jsSource, className);
15993
+ if (foundInJs) {
15994
+ foundClassDeclaration = foundInJs.classNode;
15995
+ foundClassSource = foundInJs.sourceFile;
15996
+ }
15997
+ }
15850
15998
  if (!foundClassDeclaration) warnMixinFactoryClassNotFound(buildCtx, className, classDeclaration);
15851
15999
  }
15852
16000
  if (foundClassDeclaration && !dependentClasses.some((dc) => dc.classNode === foundClassDeclaration)) {
15853
16001
  dependentClasses.push({
15854
16002
  classNode: foundClassDeclaration,
15855
- sourceFile: foundSource,
15856
- fileName: foundFile.resolvedModule.resolvedFileName
16003
+ sourceFile: foundClassSource,
16004
+ fileName: foundClassSource.fileName
15857
16005
  });
15858
16006
  if (keepLooking) buildExtendsTree(compilerCtx, foundClassDeclaration, dependentClasses, typeChecker, buildCtx, ogModule);
15859
16007
  }
@@ -16260,19 +16408,6 @@ function getExtendsClassNames(node) {
16260
16408
  if (ts.isCallExpression(expr) && expr.expression.getText() === "Mixin") return expr.arguments.filter(ts.isIdentifier).map((id) => id.text);
16261
16409
  return [];
16262
16410
  }
16263
- function findImportSpecifier(sf, localName) {
16264
- for (const stmt of sf.statements) {
16265
- if (!ts.isImportDeclaration(stmt) || !ts.isStringLiteral(stmt.moduleSpecifier)) continue;
16266
- const clause = stmt.importClause;
16267
- if (!clause) continue;
16268
- if (clause.name?.text === localName) return stmt.moduleSpecifier.text;
16269
- const bindings = clause.namedBindings;
16270
- if (bindings && ts.isNamedImports(bindings)) {
16271
- for (const el of bindings.elements) if (el.name.text === localName) return stmt.moduleSpecifier.text;
16272
- }
16273
- }
16274
- return null;
16275
- }
16276
16411
  /**
16277
16412
  * A single-file mini-program (see `convertInMemorySourceDecorators`) can
16278
16413
  * never load an imported module's own `SourceFile`, so a type that's
@@ -16296,7 +16431,7 @@ function reclassifyGlobalTypeReferences(members, declaringSf, declaringPath, res
16296
16431
  if (!references) return;
16297
16432
  Object.entries(references).forEach(([typeName, reference]) => {
16298
16433
  if (reference.location !== "global") return;
16299
- const specifier = findImportSpecifier(declaringSf, typeName);
16434
+ const specifier = findImportOrigin(declaringSf, typeName)?.moduleSpecifier;
16300
16435
  if (!specifier) return;
16301
16436
  const resolved = resolveImport(specifier, declaringPath);
16302
16437
  reference.location = "import";
@@ -16319,7 +16454,7 @@ function reclassifyGlobalTypeReferences(members, declaringSf, declaringPath, res
16319
16454
  * differ from `sf`/`path` if resolved through a re-export), or `undefined`
16320
16455
  */
16321
16456
  function findDeclarationOrReExport(sf, path, name, resolveImport) {
16322
- const direct = sf.statements.find(matchesNamedDeclaration(name));
16457
+ const direct = findStatementByName(sf, name);
16323
16458
  if (direct) return {
16324
16459
  statement: direct,
16325
16460
  sourceFile: sf,
@@ -16332,7 +16467,7 @@ function findDeclarationOrReExport(sf, path, name, resolveImport) {
16332
16467
  const { code, path: resolvedPath } = resolved;
16333
16468
  const isTs = resolvedPath.endsWith(".tsx") || resolvedPath.endsWith(".ts");
16334
16469
  const reExportSf = ts.createSourceFile(resolvedPath, code, ts.ScriptTarget.ESNext, true, isTs ? ts.ScriptKind.TSX : ts.ScriptKind.JS);
16335
- const statement = reExportSf.statements.find(matchesNamedDeclaration(reExport.localName));
16470
+ const statement = findStatementByName(reExportSf, reExport.localName);
16336
16471
  if (!statement) return void 0;
16337
16472
  return {
16338
16473
  statement,
@@ -16369,7 +16504,7 @@ function resolveAncestors(classNode, sf, path, resolveImport, visited, ancestors
16369
16504
  let foundSf = sf;
16370
16505
  let foundPath = path;
16371
16506
  let keepLooking = true;
16372
- const sameFileStatement = sf.statements.find(matchesNamedDeclaration(parentName));
16507
+ const sameFileStatement = findStatementByName(sf, parentName);
16373
16508
  if (sameFileStatement) {
16374
16509
  if (ts.isClassDeclaration(sameFileStatement)) foundClass = sameFileStatement;
16375
16510
  else {
@@ -16378,7 +16513,7 @@ function resolveAncestors(classNode, sf, path, resolveImport, visited, ancestors
16378
16513
  if (!foundClass) warnMixinFactoryClassNotFound(buildCtx, parentName, rootClassDeclaration);
16379
16514
  }
16380
16515
  } else {
16381
- const specifier = findImportSpecifier(sf, parentName);
16516
+ const specifier = findImportOrigin(sf, parentName)?.moduleSpecifier;
16382
16517
  if (!specifier) continue;
16383
16518
  const resolved = resolveImport(specifier, path);
16384
16519
  if (!resolved) continue;
@@ -21898,6 +22033,39 @@ const DEFAULT_BROWSER_TARGETS = [
21898
22033
  //#endregion
21899
22034
  //#region src/compiler/style/css-parser/parse-css.ts
21900
22035
  /**
22036
+ * Splits a selector list on top-level commas in a single pass: a comma only
22037
+ * splits when it's outside a quoted string and at paren depth 0, so commas in
22038
+ * `:is(:a,:has(:b))` or `[title="a,b"]` aren't treated as separators.
22039
+ * Backslash escapes (inside or outside a string) are skipped so they can't shift state,
22040
+ * so e.g. `[title="a\,b"]` is treated as a single selector.
22041
+ * @param selectors The selector list to split
22042
+ * @returns An array of selectors, with whitespace trimmed from each selector
22043
+ */
22044
+ const splitSelectorList = (selectors) => {
22045
+ const parts = [];
22046
+ let depth = 0;
22047
+ let quote = null;
22048
+ let start = 0;
22049
+ for (let i = 0; i < selectors.length; i++) {
22050
+ const ch = selectors[i];
22051
+ if (quote) {
22052
+ if (ch === "\\") i++;
22053
+ else if (ch === quote) quote = null;
22054
+ continue;
22055
+ }
22056
+ if (ch === "\"" || ch === "'") quote = ch;
22057
+ else if (ch === "\\") i++;
22058
+ else if (ch === "(") depth++;
22059
+ else if (ch === ")") depth = Math.max(0, depth - 1);
22060
+ else if (ch === "," && depth === 0) {
22061
+ parts.push(selectors.slice(start, i));
22062
+ start = i + 1;
22063
+ }
22064
+ }
22065
+ parts.push(selectors.slice(start));
22066
+ return parts.map((s) => s.trim());
22067
+ };
22068
+ /**
21901
22069
  * Parses CSS string input into an AST representation.
21902
22070
  * Used for minification, finding & resolving URLs and during SSR / prerendering, removing unused selectors.
21903
22071
  *
@@ -22022,11 +22190,8 @@ const parseCss = (css, filePath) => {
22022
22190
  const selector = () => {
22023
22191
  const m = match(/^([^{]+)/);
22024
22192
  if (!m) return null;
22025
- return trim(m[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, "").replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(str) {
22026
- return str.replace(/,/g, "‌");
22027
- }).split(/\s*(?![^(]*\)),\s*/).map(function(s) {
22028
- return s.replace(/\u200C/g, ",");
22029
- });
22193
+ const cleaned = trim(m[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, "");
22194
+ return splitSelectorList(cleaned);
22030
22195
  };
22031
22196
  const declaration = () => {
22032
22197
  const pos = position();
@@ -12358,6 +12358,39 @@ const TASK_CANCELED_MSG = `task canceled`;
12358
12358
  //#endregion
12359
12359
  //#region src/compiler/style/css-parser/parse-css.ts
12360
12360
  /**
12361
+ * Splits a selector list on top-level commas in a single pass: a comma only
12362
+ * splits when it's outside a quoted string and at paren depth 0, so commas in
12363
+ * `:is(:a,:has(:b))` or `[title="a,b"]` aren't treated as separators.
12364
+ * Backslash escapes (inside or outside a string) are skipped so they can't shift state,
12365
+ * so e.g. `[title="a\,b"]` is treated as a single selector.
12366
+ * @param selectors The selector list to split
12367
+ * @returns An array of selectors, with whitespace trimmed from each selector
12368
+ */
12369
+ const splitSelectorList = (selectors) => {
12370
+ const parts = [];
12371
+ let depth = 0;
12372
+ let quote = null;
12373
+ let start = 0;
12374
+ for (let i = 0; i < selectors.length; i++) {
12375
+ const ch = selectors[i];
12376
+ if (quote) {
12377
+ if (ch === "\\") i++;
12378
+ else if (ch === quote) quote = null;
12379
+ continue;
12380
+ }
12381
+ if (ch === "\"" || ch === "'") quote = ch;
12382
+ else if (ch === "\\") i++;
12383
+ else if (ch === "(") depth++;
12384
+ else if (ch === ")") depth = Math.max(0, depth - 1);
12385
+ else if (ch === "," && depth === 0) {
12386
+ parts.push(selectors.slice(start, i));
12387
+ start = i + 1;
12388
+ }
12389
+ }
12390
+ parts.push(selectors.slice(start));
12391
+ return parts.map((s) => s.trim());
12392
+ };
12393
+ /**
12361
12394
  * Parses CSS string input into an AST representation.
12362
12395
  * Used for minification, finding & resolving URLs and during SSR / prerendering, removing unused selectors.
12363
12396
  *
@@ -12482,11 +12515,8 @@ const parseCss = (css, filePath) => {
12482
12515
  const selector = () => {
12483
12516
  const m = match(/^([^{]+)/);
12484
12517
  if (!m) return null;
12485
- return trim(m[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, "").replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(str) {
12486
- return str.replace(/,/g, "‌");
12487
- }).split(/\s*(?![^(]*\)),\s*/).map(function(s) {
12488
- return s.replace(/\u200C/g, ",");
12489
- });
12518
+ const cleaned = trim(m[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, "");
12519
+ return splitSelectorList(cleaned);
12490
12520
  };
12491
12521
  const declaration = () => {
12492
12522
  const pos = position();
@@ -1,4 +1,4 @@
1
- import { l as createWorkerMessageHandler } from "../../compiler-2EypBn_Y.mjs";
1
+ import { l as createWorkerMessageHandler } from "../../compiler-BjKDj129.mjs";
2
2
  import { t as createNodeSys } from "../../node-HKfDhPR3.mjs";
3
3
  //#region src/sys/node/node-worker-thread.ts
4
4
  /**
@@ -32,7 +32,7 @@ import "@rollup/pluginutils";
32
32
  import { createHash } from "crypto";
33
33
  import { afterAll, vi } from "vitest";
34
34
  //#region src/version.ts
35
- const version = "5.0.0-beta.11";
35
+ const version = "5.0.0-beta.12";
36
36
  const MEMBER_FLAGS = {
37
37
  String: 1,
38
38
  Number: 2,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stencil/core",
3
- "version": "5.0.0-beta.11",
3
+ "version": "5.0.0-beta.12",
4
4
  "description": "A Compiler for Web Components and Progressive Web Apps",
5
5
  "keywords": [
6
6
  "components",
@@ -125,9 +125,9 @@
125
125
  "terser": "^5.50.0",
126
126
  "tinyglobby": "^0.2.17",
127
127
  "typescript": ">5.0.0 <7.0.0",
128
- "@stencil/cli": "5.0.0-beta.11",
129
- "@stencil/dev-server": "5.0.0-beta.11",
130
- "@stencil/mock-doc": "5.0.0-beta.11"
128
+ "@stencil/cli": "5.0.0-beta.12",
129
+ "@stencil/dev-server": "5.0.0-beta.12",
130
+ "@stencil/mock-doc": "5.0.0-beta.12"
131
131
  },
132
132
  "devDependencies": {
133
133
  "@ionic/prettier-config": "^4.0.0",