@stencil/core 2.15.2 → 2.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/cli/index.cjs +6 -6
  2. package/cli/index.js +6 -6
  3. package/cli/package.json +1 -1
  4. package/compiler/package.json +1 -1
  5. package/compiler/stencil.js +439 -102
  6. package/compiler/stencil.min.js +2 -2
  7. package/dependencies.json +1 -1
  8. package/dev-server/client/index.js +1 -1
  9. package/dev-server/client/package.json +1 -1
  10. package/dev-server/client/test/hmr-util.spec.d.ts +1 -0
  11. package/dev-server/client/test/status.spec.d.ts +1 -0
  12. package/dev-server/connector.html +2 -2
  13. package/dev-server/index.js +1 -1
  14. package/dev-server/package.json +1 -1
  15. package/dev-server/server-process.js +3 -3
  16. package/internal/app-data/package.json +1 -1
  17. package/internal/client/css-shim.js +1 -1
  18. package/internal/client/dom.js +1 -1
  19. package/internal/client/index.js +11 -9
  20. package/internal/client/package.json +1 -1
  21. package/internal/client/patch-browser.js +1 -1
  22. package/internal/client/patch-esm.js +1 -1
  23. package/internal/client/shadow-css.js +2 -3
  24. package/internal/hydrate/index.js +34 -29
  25. package/internal/hydrate/package.json +1 -1
  26. package/internal/hydrate/shadow-css.js +9 -9
  27. package/internal/package.json +1 -1
  28. package/internal/stencil-public-compiler.d.ts +66 -2
  29. package/internal/stencil-public-docs.d.ts +3 -0
  30. package/internal/testing/index.js +34 -29
  31. package/internal/testing/package.json +1 -1
  32. package/internal/testing/shadow-css.js +9 -9
  33. package/mock-doc/index.cjs +6 -2
  34. package/mock-doc/index.d.ts +8 -2
  35. package/mock-doc/index.js +6 -2
  36. package/mock-doc/package.json +1 -1
  37. package/package.json +21 -14
  38. package/screenshot/package.json +1 -1
  39. package/sys/node/index.js +1 -1
  40. package/sys/node/package.json +1 -1
  41. package/sys/node/worker.js +1 -1
  42. package/testing/index.js +2 -2
  43. package/testing/jest/test/jest-config.spec.d.ts +1 -0
  44. package/testing/jest/test/jest-preprocessor.spec.d.ts +1 -0
  45. package/testing/jest/test/jest-runner.spec.d.ts +1 -0
  46. package/testing/jest/test/jest-serializer.spec.d.ts +1 -0
  47. package/testing/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- Stencil Compiler v2.15.2 | MIT Licensed | https://stenciljs.com
2
+ Stencil Compiler v2.16.0 | MIT Licensed | https://stenciljs.com
3
3
  */
4
4
  (function(exports) {
5
5
  'use strict';
@@ -2236,10 +2236,36 @@ const createWebWorkerMainController = (sys, maxConcurrentWorkers) => {
2236
2236
 
2237
2237
  const COMMON_DIR_MODULE_EXTS = ['.tsx', '.ts', '.mjs', '.js', '.jsx', '.json', '.md'];
2238
2238
  const COMMON_DIR_FILENAMES = ['package.json', 'index.js', 'index.mjs'];
2239
+ /**
2240
+ * Determine if a stringified file path is a TypeScript declaration file based on the extension at the end of the path.
2241
+ * @param p the path to evaluate
2242
+ * @returns `true` if the path ends in `.d.ts` (case-sensitive), `false` otherwise.
2243
+ */
2239
2244
  const isDtsFile = (p) => p.endsWith('.d.ts');
2245
+ /**
2246
+ * Determine if a stringified file path is a TypeScript file based on the extension at the end of the path. This
2247
+ * function does _not_ consider type declaration files (`.d.ts` files) to be TypeScript files.
2248
+ * @param p the path to evaluate
2249
+ * @returns `true` if the path ends in `.ts` (case-sensitive) but does _not_ end in `.d.ts`, `false` otherwise.
2250
+ */
2240
2251
  const isTsFile = (p) => !isDtsFile(p) && p.endsWith('.ts');
2252
+ /**
2253
+ * Determine if a stringified file path is a TSX file based on the extension at the end of the path
2254
+ * @param p the path to evaluate
2255
+ * @returns `true` if the path ends in `.tsx` (case-sensitive), `false` otherwise.
2256
+ */
2241
2257
  const isTsxFile = (p) => p.endsWith('.tsx');
2258
+ /**
2259
+ * Determine if a stringified file path is a JSX file based on the extension at the end of the path
2260
+ * @param p the path to evaluate
2261
+ * @returns `true` if the path ends in `.jsx` (case-sensitive), `false` otherwise.
2262
+ */
2242
2263
  const isJsxFile = (p) => p.endsWith('.jsx');
2264
+ /**
2265
+ * Determine if a stringified file path is a JavaScript file based on the extension at the end of the path
2266
+ * @param p the path to evaluate
2267
+ * @returns `true` if the path ends in `.js` (case-sensitive), `false` otherwise.
2268
+ */
2243
2269
  const isJsFile = (p) => p.endsWith('.js');
2244
2270
  const isJsonFile = (p) => p.endsWith('.json');
2245
2271
  const getCommonDirName = (dirPath, fileName) => dirPath + '/' + fileName;
@@ -3974,7 +4000,7 @@ const createCustomResolverAsync = (sys, inMemoryFs, exts) => {
3974
4000
  };
3975
4001
  };
3976
4002
 
3977
- const buildId = '20220509165949';
4003
+ const buildId = '20220531163847';
3978
4004
  const minfyJsId = 'terser5.6.1_7';
3979
4005
  const optimizeCssId = 'autoprefixer10.2.5_postcss8.2.13_7';
3980
4006
  const parse5Version = '6.0.1';
@@ -3982,8 +4008,8 @@ const rollupVersion = '2.42.3';
3982
4008
  const sizzleVersion = '2.42.3';
3983
4009
  const terserVersion = '5.6.1';
3984
4010
  const typescriptVersion = '4.5.4';
3985
- const vermoji = '🎢';
3986
- const version$3 = '2.15.2';
4011
+ const vermoji = '🎉';
4012
+ const version$3 = '2.16.0';
3987
4013
  const versions = {
3988
4014
  stencil: version$3,
3989
4015
  parse5: parse5Version,
@@ -11000,7 +11026,6 @@ const CSS_PROP_ANNOTATION = `@prop`;
11000
11026
  const safeSelector = (selector) => {
11001
11027
  const placeholders = [];
11002
11028
  let index = 0;
11003
- let content;
11004
11029
  // Replaces attribute selectors with placeholders.
11005
11030
  // The WS in [attr="va lue"] would otherwise be interpreted as a selector separator.
11006
11031
  selector = selector.replace(/(\[[^\]]*\])/g, (_, keep) => {
@@ -11011,7 +11036,7 @@ const safeSelector = (selector) => {
11011
11036
  });
11012
11037
  // Replaces the expression in `:nth-child(2n + 1)` with a placeholder.
11013
11038
  // WS and "+" would otherwise be interpreted as selector separators.
11014
- content = selector.replace(/(:nth-[-\w]+)(\([^)]+\))/g, (_, pseudo, exp) => {
11039
+ const content = selector.replace(/(:nth-[-\w]+)(\([^)]+\))/g, (_, pseudo, exp) => {
11015
11040
  const replaceBy = `__ph-${index}__`;
11016
11041
  placeholders.push(exp);
11017
11042
  index++;
@@ -12032,25 +12057,33 @@ const isOutputTargetWww = (o) => o.type === WWW;
12032
12057
  const isOutputTargetStats = (o) => o.type === STATS;
12033
12058
  const isOutputTargetDistTypes = (o) => o.type === DIST_TYPES;
12034
12059
  const getComponentsFromModules = (moduleFiles) => sortBy(flatOne(moduleFiles.map((m) => m.cmps)), (c) => c.tagName);
12035
- const ANGULAR = `angular`;
12060
+ const ANGULAR = 'angular';
12036
12061
  const COPY = 'copy';
12037
- const CUSTOM = `custom`;
12038
- const DIST = `dist`;
12039
- const DIST_COLLECTION = `dist-collection`;
12040
- const DIST_CUSTOM_ELEMENTS = `dist-custom-elements`;
12041
- const DIST_CUSTOM_ELEMENTS_BUNDLE = `dist-custom-elements-bundle`;
12042
- const DIST_TYPES = `dist-types`;
12043
- const DIST_HYDRATE_SCRIPT = `dist-hydrate-script`;
12044
- const DIST_LAZY = `dist-lazy`;
12045
- const DIST_LAZY_LOADER = `dist-lazy-loader`;
12062
+ const CUSTOM = 'custom';
12063
+ const DIST = 'dist';
12064
+ const DIST_COLLECTION = 'dist-collection';
12065
+ const DIST_CUSTOM_ELEMENTS = 'dist-custom-elements';
12066
+ const DIST_CUSTOM_ELEMENTS_BUNDLE = 'dist-custom-elements-bundle';
12067
+ const DIST_TYPES = 'dist-types';
12068
+ const DIST_HYDRATE_SCRIPT = 'dist-hydrate-script';
12069
+ const DIST_LAZY = 'dist-lazy';
12070
+ const DIST_LAZY_LOADER = 'dist-lazy-loader';
12046
12071
  const DIST_GLOBAL_STYLES = 'dist-global-styles';
12047
12072
  const DOCS_CUSTOM = 'docs-custom';
12048
- const DOCS_JSON = `docs-json`;
12049
- const DOCS_README = `docs-readme`;
12050
- const DOCS_VSCODE = `docs-vscode`;
12051
- const STATS = `stats`;
12052
- const WWW = `www`;
12053
- const VALID_TYPES = [
12073
+ const DOCS_JSON = 'docs-json';
12074
+ const DOCS_README = 'docs-readme';
12075
+ const DOCS_VSCODE = 'docs-vscode';
12076
+ const STATS = 'stats';
12077
+ const WWW = 'www';
12078
+ /**
12079
+ * Valid output targets to specify in a Stencil config.
12080
+ *
12081
+ * Note that there are some output targets (e.g. `DIST_TYPES`) which are
12082
+ * programmatically set as output targets by the compiler when other output
12083
+ * targets (in that case `DIST`) are set, but which are _not_ supported in a
12084
+ * Stencil config. This is enforced in the output target validation code.
12085
+ */
12086
+ const VALID_CONFIG_OUTPUT_TARGETS = [
12054
12087
  // DIST
12055
12088
  WWW,
12056
12089
  DIST,
@@ -12070,6 +12103,20 @@ const VALID_TYPES = [
12070
12103
  CUSTOM,
12071
12104
  STATS,
12072
12105
  ];
12106
+ /**
12107
+ * Check whether a given output target is a valid one to be set in a Stencil config
12108
+ *
12109
+ * @param targetType the type which we want to check
12110
+ * @returns whether or not the targetType is a valid, configurable output target.
12111
+ */
12112
+ function isValidConfigOutputTarget(targetType) {
12113
+ // unfortunately `includes` is typed on `ReadonlyArray<T>` as `(el: T):
12114
+ // boolean` so a `string` cannot be passed to `includes` on a
12115
+ // `ReadonlyArray` 😢 thus we `as any`
12116
+ //
12117
+ // see microsoft/TypeScript#31018 for some discussion of this
12118
+ return VALID_CONFIG_OUTPUT_TARGETS.includes(targetType);
12119
+ }
12073
12120
  const GENERATED_DTS$1 = 'components.d.ts';
12074
12121
 
12075
12122
  var concatMap$1 = function (xs, fn) {
@@ -13675,6 +13722,7 @@ const generateBuildResults = (config, compilerCtx, buildCtx) => {
13675
13722
  * @returns CompilerBuildStats or an Object including diagnostics.
13676
13723
  */
13677
13724
  function generateBuildStats(config, buildCtx) {
13725
+ // TODO(STENCIL-461): Investigate making this return only a single type
13678
13726
  const buildResults = buildCtx.buildResults;
13679
13727
  let jsonData;
13680
13728
  try {
@@ -13767,7 +13815,7 @@ function sanitizeBundlesForStats(bundleArray) {
13767
13815
  });
13768
13816
  }
13769
13817
  function getSourceGraph(config, buildCtx) {
13770
- let sourceGraph = {};
13818
+ const sourceGraph = {};
13771
13819
  sortBy(buildCtx.moduleFiles, (m) => m.sourceFilePath).forEach((moduleFile) => {
13772
13820
  const key = relativePath$1(config, moduleFile.sourceFilePath);
13773
13821
  sourceGraph[key] = moduleFile.localImports.map((localImport) => relativePath$1(config, localImport)).sort();
@@ -15515,7 +15563,11 @@ class MockNode {
15515
15563
  if (otherNode === this) {
15516
15564
  return true;
15517
15565
  }
15518
- return this.childNodes.includes(otherNode);
15566
+ const childNodes = Array.from(this.childNodes);
15567
+ if (childNodes.includes(otherNode)) {
15568
+ return true;
15569
+ }
15570
+ return childNodes.some((node) => this.contains.bind(node)(otherNode));
15519
15571
  }
15520
15572
  removeChild(childNode) {
15521
15573
  const index = this.childNodes.indexOf(childNode);
@@ -40773,7 +40825,7 @@ const parseDevModuleUrl = (config, u) => {
40773
40825
  const url = new URL(u, 'https://stenciljs.com');
40774
40826
  let reqPath = basename(url.pathname);
40775
40827
  reqPath = reqPath.substring(0, reqPath.length - 3);
40776
- let splt = reqPath.split('@');
40828
+ const splt = reqPath.split('@');
40777
40829
  if (splt.length === 2) {
40778
40830
  parsedUrl.nodeModuleId = decodeURIComponent(splt[0]);
40779
40831
  parsedUrl.nodeModuleVersion = decodeURIComponent(splt[1]);
@@ -42658,7 +42710,14 @@ const parse$1 = (input, options) => {
42658
42710
  }
42659
42711
 
42660
42712
  if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) {
42661
- output = token.close = `)${rest})${extglobStar})`;
42713
+ // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis.
42714
+ // In this case, we need to parse the string and use it in the output of the original pattern.
42715
+ // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`.
42716
+ //
42717
+ // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`.
42718
+ const expression = parse$1(rest, { ...options, fastpaths: false }).output;
42719
+
42720
+ output = token.close = `)${expression})${extglobStar})`;
42662
42721
  }
42663
42722
 
42664
42723
  if (token.prev.type === 'bos') {
@@ -55414,9 +55473,9 @@ const proxyCustomElement = (compilerCtx, transformOpts) => {
55414
55473
  return tsSourceFile;
55415
55474
  }
55416
55475
  const principalComponent = moduleFile.cmps[0];
55417
- for (let [stmtIndex, stmt] of tsSourceFile.statements.entries()) {
55476
+ for (const [stmtIndex, stmt] of tsSourceFile.statements.entries()) {
55418
55477
  if (t.isVariableStatement(stmt)) {
55419
- for (let [declarationIndex, declaration] of stmt.declarationList.declarations.entries()) {
55478
+ for (const [declarationIndex, declaration] of stmt.declarationList.declarations.entries()) {
55420
55479
  if (declaration.name.getText() !== principalComponent.componentClassName) {
55421
55480
  continue;
55422
55481
  }
@@ -56581,6 +56640,20 @@ const strickCheckDocs = (config, docsData) => {
56581
56640
  });
56582
56641
  };
56583
56642
 
56643
+ /**
56644
+ * Generate [custom data](https://github.com/microsoft/vscode-custom-data) to augment existing HTML types in VS Code.
56645
+ * This function writes the custom data as a JSON file to disk, which can be used in VS Code to inform the IDE about
56646
+ * custom elements generated by Stencil.
56647
+ *
56648
+ * The JSON generated by this function must conform to the
56649
+ * [HTML custom data schema](https://github.com/microsoft/vscode-html-languageservice/blob/e7ae8a7170df5e721a13cee1b86e293b24eb3b20/docs/customData.schema.json).
56650
+ *
56651
+ * This function generates custom data for HTML only at this time (it does not generate custom data for CSS).
56652
+ *
56653
+ * @param compilerCtx the current compiler context
56654
+ * @param docsData an intermediate representation documentation derived from compiled Stencil components
56655
+ * @param outputTargets the output target(s) the associated with the current build
56656
+ */
56584
56657
  const generateVscodeDocs = async (compilerCtx, docsData, outputTargets) => {
56585
56658
  const vsCodeOutputTargets = outputTargets.filter(isOutputTargetDocsVscode);
56586
56659
  if (vsCodeOutputTargets.length === 0) {
@@ -56588,6 +56661,13 @@ const generateVscodeDocs = async (compilerCtx, docsData, outputTargets) => {
56588
56661
  }
56589
56662
  await Promise.all(vsCodeOutputTargets.map(async (outputTarget) => {
56590
56663
  const json = {
56664
+ /**
56665
+ * the 'version' top-level field is required by the schema. changes to the JSON generated by Stencil must:
56666
+ * - comply with v1.X of the schema _OR_
56667
+ * - increment this field as a part of updating the JSON generation. This should be considered a breaking change
56668
+ *
56669
+ * {@link https://github.com/microsoft/vscode-html-languageservice/blob/e7ae8a7170df5e721a13cee1b86e293b24eb3b20/src/htmlLanguageTypes.ts#L184}
56670
+ */
56591
56671
  version: 1.1,
56592
56672
  tags: docsData.components.map((cmp) => ({
56593
56673
  name: cmp.tag,
@@ -56595,20 +56675,31 @@ const generateVscodeDocs = async (compilerCtx, docsData, outputTargets) => {
56595
56675
  kind: 'markdown',
56596
56676
  value: cmp.docs,
56597
56677
  },
56598
- attributes: cmp.props.filter((p) => p.attr).map(serializeAttribute),
56678
+ attributes: cmp.props
56679
+ .filter((p) => p.attr !== undefined && p.attr.length > 0)
56680
+ .map(serializeAttribute),
56599
56681
  references: getReferences(cmp, outputTarget.sourceCodeBaseUrl),
56600
56682
  })),
56601
56683
  };
56684
+ // fields in the custom data may have a value of `undefined`. calling `stringify` will remove such fields.
56602
56685
  const jsonContent = JSON.stringify(json, null, 2);
56603
56686
  await compilerCtx.fs.writeFile(outputTarget.file, jsonContent);
56604
56687
  }));
56605
56688
  };
56689
+ /**
56690
+ * Generate a 'references' section for a component's documentation.
56691
+ * @param cmp the Stencil component to generate a references section for
56692
+ * @param repoBaseUrl an optional URL, that when provided, will add a reference to the source code for the component
56693
+ * @returns the generated references section, or undefined if no references could be generated
56694
+ */
56606
56695
  const getReferences = (cmp, repoBaseUrl) => {
56696
+ var _a;
56697
+ // collect any `@reference` JSDoc tags on the component
56607
56698
  const references = getNameText('reference', cmp.docsTags).map(([name, url]) => ({ name, url }));
56608
56699
  if (repoBaseUrl) {
56609
56700
  references.push({
56610
56701
  name: 'Source code',
56611
- url: join(repoBaseUrl, cmp.filePath),
56702
+ url: join(repoBaseUrl, (_a = cmp.filePath) !== null && _a !== void 0 ? _a : ''),
56612
56703
  });
56613
56704
  }
56614
56705
  if (references.length > 0) {
@@ -56616,14 +56707,19 @@ const getReferences = (cmp, repoBaseUrl) => {
56616
56707
  }
56617
56708
  return undefined;
56618
56709
  };
56710
+ /**
56711
+ * Serialize a component's class member decorated with `@Prop` to be written to disk
56712
+ * @param prop the intermediate representation of the documentation to serialize
56713
+ * @returns the serialized data
56714
+ */
56619
56715
  const serializeAttribute = (prop) => {
56620
56716
  const attribute = {
56621
56717
  name: prop.attr,
56622
56718
  description: prop.docs,
56623
56719
  };
56624
56720
  const values = prop.values
56625
- .filter(({ type, value }) => type === 'string' && value !== undefined)
56626
- .map(({ value }) => ({ name: value }));
56721
+ .filter((jsonDocValue) => jsonDocValue.type === 'string' && jsonDocValue.value !== undefined)
56722
+ .map((jsonDocValue) => ({ name: jsonDocValue.value }));
56627
56723
  if (values.length > 0) {
56628
56724
  attribute.values = values;
56629
56725
  }
@@ -57434,6 +57530,7 @@ const getBundleId = async (config, entryKey, shouldHash, code, sufix) => {
57434
57530
  };
57435
57531
 
57436
57532
  const generateLazyModules = async (config, compilerCtx, buildCtx, outputTargetType, destinations, results, sourceTarget, isBrowserBuild, sufix) => {
57533
+ var _a;
57437
57534
  if (!Array.isArray(destinations) || destinations.length === 0) {
57438
57535
  return [];
57439
57536
  }
@@ -57441,14 +57538,15 @@ const generateLazyModules = async (config, compilerCtx, buildCtx, outputTargetTy
57441
57538
  const rollupResults = results.filter((r) => r.type === 'chunk');
57442
57539
  const entryComponentsResults = rollupResults.filter((rollupResult) => rollupResult.isComponent);
57443
57540
  const chunkResults = rollupResults.filter((rollupResult) => !rollupResult.isComponent && !rollupResult.isEntry);
57444
- const [bundleModules] = await Promise.all([
57445
- Promise.all(entryComponentsResults.map((rollupResult) => {
57446
- return generateLazyEntryModule(config, compilerCtx, buildCtx, rollupResult, outputTargetType, destinations, sourceTarget, shouldMinify, isBrowserBuild, sufix);
57447
- })),
57448
- Promise.all(chunkResults.map((rollupResult) => {
57449
- return writeLazyChunk(config, compilerCtx, buildCtx, rollupResult, outputTargetType, destinations, sourceTarget, shouldMinify, isBrowserBuild);
57450
- })),
57451
- ]);
57541
+ const bundleModules = await Promise.all(entryComponentsResults.map((rollupResult) => {
57542
+ return generateLazyEntryModule(config, compilerCtx, buildCtx, rollupResult, outputTargetType, destinations, sourceTarget, shouldMinify, isBrowserBuild, sufix);
57543
+ }));
57544
+ if (!!((_a = config.extras) === null || _a === void 0 ? void 0 : _a.experimentalImportInjection) && !isBrowserBuild) {
57545
+ addStaticImports(rollupResults, bundleModules);
57546
+ }
57547
+ await Promise.all(chunkResults.map((rollupResult) => {
57548
+ return writeLazyChunk(config, compilerCtx, buildCtx, rollupResult, outputTargetType, destinations, sourceTarget, shouldMinify, isBrowserBuild);
57549
+ }));
57452
57550
  const lazyRuntimeData = formatLazyBundlesRuntimeMeta(bundleModules);
57453
57551
  const entryResults = rollupResults.filter((rollupResult) => !rollupResult.isComponent && rollupResult.isEntry);
57454
57552
  await Promise.all(entryResults.map((rollupResult) => {
@@ -57463,6 +57561,74 @@ const generateLazyModules = async (config, compilerCtx, buildCtx, outputTargetTy
57463
57561
  }));
57464
57562
  return bundleModules;
57465
57563
  };
57564
+ /**
57565
+ * Add imports for each bundle to Stencil's lazy loader. Some bundlers that are built atop of Rollup strictly impose
57566
+ * the limitations that are laid out in https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations.
57567
+ * This function injects an explicit import statement for each bundle that can be lazily loaded.
57568
+ * @param rollupChunkResults the results of running Rollup across a Stencil project
57569
+ * @param bundleModules lazy-loadable modules that can be resolved at runtime
57570
+ */
57571
+ const addStaticImports = (rollupChunkResults, bundleModules) => {
57572
+ rollupChunkResults.filter(isStencilCoreResult).forEach((index) => {
57573
+ const generateCjs = isCjsFormat(index) ? generateCaseClauseCjs : generateCaseClause;
57574
+ index.code = index.code.replace('/*!__STENCIL_STATIC_IMPORT_SWITCH__*/', `
57575
+ if (!hmrVersionId || !BUILD.hotModuleReplacement) {
57576
+ const processMod = importedModule => {
57577
+ cmpModules.set(bundleId, importedModule);
57578
+ return importedModule[exportName];
57579
+ }
57580
+ switch(bundleId) {
57581
+ ${bundleModules.map((mod) => generateCjs(mod.output.bundleId)).join('')}
57582
+ }
57583
+ }`);
57584
+ });
57585
+ };
57586
+ /**
57587
+ * Determine if a Rollup output chunk contains Stencil runtime code
57588
+ * @param rollupChunkResult the rollup chunk output to test
57589
+ * @returns true if the output chunk contains Stencil runtime code, false otherwise
57590
+ */
57591
+ const isStencilCoreResult = (rollupChunkResult) => {
57592
+ return (rollupChunkResult.isCore &&
57593
+ rollupChunkResult.entryKey === 'index' &&
57594
+ (rollupChunkResult.moduleFormat === 'es' ||
57595
+ rollupChunkResult.moduleFormat === 'esm' ||
57596
+ isCjsFormat(rollupChunkResult)));
57597
+ };
57598
+ /**
57599
+ * Helper function to determine if a Rollup chunk has a commonjs module format
57600
+ * @param rollupChunkResult the Rollup result to test
57601
+ * @returns true if the Rollup chunk has a commonjs module format, false otherwise
57602
+ */
57603
+ const isCjsFormat = (rollupChunkResult) => {
57604
+ return rollupChunkResult.moduleFormat === 'cjs' || rollupChunkResult.moduleFormat === 'commonjs';
57605
+ };
57606
+ /**
57607
+ * Generate a 'case' clause to be used within a `switch` statement. The case clause generated will key-off the provided
57608
+ * bundle ID for a component, and load a file (tied to that ID) at runtime.
57609
+ * @param bundleId the name of the bundle to load
57610
+ * @returns the case clause that will load the component's file at runtime
57611
+ */
57612
+ const generateCaseClause = (bundleId) => {
57613
+ return `
57614
+ case '${bundleId}':
57615
+ return import(
57616
+ /* webpackMode: "lazy" */
57617
+ './${bundleId}.entry.js').then(processMod, consoleError);`;
57618
+ };
57619
+ /**
57620
+ * Generate a 'case' clause to be used within a `switch` statement. The case clause generated will key-off the provided
57621
+ * bundle ID for a component, and load a CommonJS file (tied to that ID) at runtime.
57622
+ * @param bundleId the name of the bundle to load
57623
+ * @returns the case clause that will load the component's file at runtime
57624
+ */
57625
+ const generateCaseClauseCjs = (bundleId) => {
57626
+ return `
57627
+ case '${bundleId}':
57628
+ return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require(
57629
+ /* webpackMode: "lazy" */
57630
+ './${bundleId}.entry.js')); }).then(processMod, consoleError);`;
57631
+ };
57466
57632
  const generateLazyEntryModule = async (config, compilerCtx, buildCtx, rollupResult, outputTargetType, destinations, sourceTarget, shouldMinify, isBrowserBuild, sufix) => {
57467
57633
  const entryModule = buildCtx.entryModules.find((entryModule) => entryModule.entryKey === rollupResult.entryKey);
57468
57634
  const shouldHash = config.hashFileNames && isBrowserBuild;
@@ -57491,7 +57657,7 @@ const writeLazyEntry = async (config, compilerCtx, buildCtx, rollupResult, outpu
57491
57657
  if (isBrowserBuild && ['loader'].includes(rollupResult.entryKey)) {
57492
57658
  return;
57493
57659
  }
57494
- let inputCode = rollupResult.code.replace(`[/*!__STENCIL_LAZY_DATA__*/]`, `${lazyRuntimeData}`);
57660
+ const inputCode = rollupResult.code.replace(`[/*!__STENCIL_LAZY_DATA__*/]`, `${lazyRuntimeData}`);
57495
57661
  const { code, sourceMap } = await convertChunk(config, compilerCtx, buildCtx, sourceTarget, shouldMinify, false, isBrowserBuild, inputCode, rollupResult.map);
57496
57662
  await Promise.all(destinations.map((dst) => {
57497
57663
  const filePath = join(dst, rollupResult.fileName);
@@ -57509,7 +57675,7 @@ const formatLazyBundlesRuntimeMeta = (bundleModules) => {
57509
57675
  return stringifyRuntimeData(lazyBundles);
57510
57676
  };
57511
57677
  const formatLazyRuntimeBundle = (bundleModule) => {
57512
- let bundleId = bundleModule.output.bundleId;
57678
+ const bundleId = bundleModule.output.bundleId;
57513
57679
  const bundleCmps = bundleModule.cmps.slice().sort(sortBundleComponents);
57514
57680
  return [bundleId, bundleCmps.map((cmp) => formatComponentRuntimeMeta(cmp, true))];
57515
57681
  };
@@ -58942,12 +59108,12 @@ const updateStencilTypesImports = (typesDir, dtsFilePath, dtsContent) => {
58942
59108
  const updateTypeIdentifierNames = (typeReferences, typeImportData, sourceFilePath, initialType) => {
58943
59109
  let currentTypeName = initialType;
58944
59110
  // iterate over each of the type references, as there may be >1 reference to inspect
58945
- for (let typeReference of Object.values(typeReferences)) {
59111
+ for (const typeReference of Object.values(typeReferences)) {
58946
59112
  const importResolvedFile = getTypeImportPath(typeReference.path, sourceFilePath);
58947
59113
  if (!typeImportData.hasOwnProperty(importResolvedFile)) {
58948
59114
  continue;
58949
59115
  }
58950
- for (let typesImportDatumElement of typeImportData[importResolvedFile]) {
59116
+ for (const typesImportDatumElement of typeImportData[importResolvedFile]) {
58951
59117
  currentTypeName = updateTypeName(currentTypeName, typesImportDatumElement);
58952
59118
  }
58953
59119
  }
@@ -59033,13 +59199,15 @@ const sortImportNames = (a, b) => {
59033
59199
  * Generates the individual event types for all @Event() decorated events in a component
59034
59200
  * @param cmpMeta component runtime metadata for a single component
59035
59201
  * @param typeImportData locally/imported/globally used type names, which may be used to prevent naming collisions
59202
+ * @param cmpClassName The pascal cased name of the component class
59036
59203
  * @returns the generated type metadata
59037
59204
  */
59038
- const generateEventTypes = (cmpMeta, typeImportData) => {
59205
+ const generateEventTypes = (cmpMeta, typeImportData, cmpClassName) => {
59039
59206
  return cmpMeta.events.map((cmpEvent) => {
59040
59207
  const name = `on${toTitleCase(cmpEvent.name)}`;
59041
- const type = getEventType$1(cmpEvent, typeImportData, cmpMeta.sourceFilePath);
59042
- return {
59208
+ const cmpEventDetailInterface = `${cmpClassName}CustomEvent`;
59209
+ const type = getEventType$1(cmpEvent, cmpEventDetailInterface, typeImportData, cmpMeta.sourceFilePath);
59210
+ const typeInfo = {
59043
59211
  name,
59044
59212
  type,
59045
59213
  optional: false,
@@ -59047,21 +59215,23 @@ const generateEventTypes = (cmpMeta, typeImportData) => {
59047
59215
  internal: cmpEvent.internal,
59048
59216
  jsdoc: getTextDocs(cmpEvent.docs),
59049
59217
  };
59218
+ return typeInfo;
59050
59219
  });
59051
59220
  };
59052
59221
  /**
59053
59222
  * Determine the correct type name for all type(s) used by a class member annotated with `@Event()`
59054
59223
  * @param cmpEvent the compiler metadata for a single `@Event()`
59224
+ * @param cmpEventDetailInterface the name of the custom event type to use in the generated type
59055
59225
  * @param typeImportData locally/imported/globally used type names, which may be used to prevent naming collisions
59056
59226
  * @param componentSourcePath the path to the component on disk
59057
59227
  * @returns the type associated with a `@Event()`
59058
59228
  */
59059
- const getEventType$1 = (cmpEvent, typeImportData, componentSourcePath) => {
59229
+ const getEventType$1 = (cmpEvent, cmpEventDetailInterface, typeImportData, componentSourcePath) => {
59060
59230
  if (!cmpEvent.complexType.original) {
59061
59231
  return 'CustomEvent';
59062
59232
  }
59063
59233
  const updatedTypeName = updateTypeIdentifierNames(cmpEvent.complexType.references, typeImportData, componentSourcePath, cmpEvent.complexType.original);
59064
- return `(event: CustomEvent<${updatedTypeName}>) => void`;
59234
+ return `(event: ${cmpEventDetailInterface}<${updatedTypeName}>) => void`;
59065
59235
  };
59066
59236
 
59067
59237
  /**
@@ -59141,7 +59311,7 @@ const generateComponentTypes = (cmp, typeImportData, areTypesInternal) => {
59141
59311
  const htmlElementName = `HTML${tagNameAsPascal}Element`;
59142
59312
  const propAttributes = generatePropTypes(cmp, typeImportData);
59143
59313
  const methodAttributes = generateMethodTypes(cmp, typeImportData);
59144
- const eventAttributes = generateEventTypes(cmp, typeImportData);
59314
+ const eventAttributes = generateEventTypes(cmp, typeImportData, tagNameAsPascal);
59145
59315
  const componentAttributes = attributesToMultiLineString([...propAttributes, ...methodAttributes], false, areTypesInternal);
59146
59316
  const isDep = cmp.isCollectionDependency;
59147
59317
  const jsxAttributes = attributesToMultiLineString([...propAttributes, ...eventAttributes], true, areTypesInternal);
@@ -59185,6 +59355,39 @@ const attributesToMultiLineString = (attributes, jsxAttributes, internal) => {
59185
59355
  return attributesStr !== '' ? `${attributesStr}\n` : '';
59186
59356
  };
59187
59357
 
59358
+ /**
59359
+ * Generates the custom event interface for each component that combines the `CustomEvent` interface with
59360
+ * the HTMLElement target. This is used to allow implementers to use strict typings on event handlers.
59361
+ *
59362
+ * The generated interface accepts a generic for the event detail type. This allows implementers to use
59363
+ * custom typings for individual events without Stencil needing to generate an interface for each event.
59364
+ *
59365
+ * @param cmp The component compiler metadata
59366
+ * @returns The generated interface type definition.
59367
+ */
59368
+ const generateEventDetailTypes = (cmp) => {
59369
+ const tagName = cmp.tagName.toLowerCase();
59370
+ const tagNameAsPascal = dashToPascalCase$1(tagName);
59371
+ const htmlElementName = `HTML${tagNameAsPascal}Element`;
59372
+ const isDep = cmp.isCollectionDependency;
59373
+ const cmpEventInterface = `${tagNameAsPascal}CustomEvent`;
59374
+ const cmpInterface = [
59375
+ `export interface ${cmpEventInterface}<T> extends CustomEvent<T> {`,
59376
+ ` detail: T;`,
59377
+ ` target: ${htmlElementName};`,
59378
+ `}`,
59379
+ ];
59380
+ return {
59381
+ isDep,
59382
+ tagName,
59383
+ tagNameAsPascal,
59384
+ htmlElementName,
59385
+ component: cmpInterface.join('\n'),
59386
+ jsx: cmpInterface.join('\n'),
59387
+ element: cmpInterface.join('\n'),
59388
+ };
59389
+ };
59390
+
59188
59391
  /**
59189
59392
  * Find all referenced types by a component and add them to the `importDataObj` parameter
59190
59393
  * @param importDataObj an output parameter that contains the imported types seen thus far by the compiler
@@ -59294,7 +59497,7 @@ const generateAppTypes = async (config, compilerCtx, buildCtx, destination) => {
59294
59497
  return hasComponentsDtsChanged;
59295
59498
  };
59296
59499
  /**
59297
- * Generates a `component.d.ts` file's contents, which contains the typings for all components in a Stencil project
59500
+ * Generates a `components.d.ts` file's contents, which contains the typings for all components in a Stencil project
59298
59501
  * @param config the Stencil configuration associated with the project being compiled
59299
59502
  * @param buildCtx the context associated with the current build
59300
59503
  * @param areTypesInternal determines if non-exported type definitions are being generated or not
@@ -59305,6 +59508,7 @@ const generateComponentTypesFile = (config, buildCtx, areTypesInternal) => {
59305
59508
  const c = [];
59306
59509
  const allTypes = new Map();
59307
59510
  const components = buildCtx.components.filter((m) => !m.isCollectionDependency);
59511
+ const componentEventDetailTypes = [];
59308
59512
  const modules = components.map((cmp) => {
59309
59513
  /**
59310
59514
  * Generate a key-value store that uses the path to the file where an import is defined as the key, and an object
@@ -59313,6 +59517,12 @@ const generateComponentTypesFile = (config, buildCtx, areTypesInternal) => {
59313
59517
  * grow as more components (with additional types) are processed.
59314
59518
  */
59315
59519
  typeImportData = updateReferenceTypeImports(typeImportData, allTypes, cmp, cmp.sourceFilePath);
59520
+ if (cmp.events.length > 0) {
59521
+ /**
59522
+ * Only generate event detail types for components that have events.
59523
+ */
59524
+ componentEventDetailTypes.push(generateEventDetailTypes(cmp));
59525
+ }
59316
59526
  return generateComponentTypes(cmp, typeImportData, areTypesInternal);
59317
59527
  });
59318
59528
  c.push(COMPONENTS_DTS_HEADER);
@@ -59339,7 +59549,10 @@ const generateComponentTypesFile = (config, buildCtx, areTypesInternal) => {
59339
59549
  })
59340
59550
  .join(`, `)} } from "${importFilePath}";`;
59341
59551
  }));
59342
- c.push(`export namespace Components {\n${modules.map((m) => `${m.component}`).join('\n')}\n}`);
59552
+ c.push(`export namespace Components {`);
59553
+ c.push(...modules.map((m) => `${m.component}`));
59554
+ c.push(`}`);
59555
+ c.push(...componentEventDetailTypes.map((m) => `${m.component}`));
59343
59556
  c.push(`declare global {`);
59344
59557
  c.push(...modules.map((m) => m.element));
59345
59558
  c.push(` interface HTMLElementTagNameMap {`);
@@ -62370,52 +62583,114 @@ const getTsOptionsToExtend = (config) => {
62370
62583
  return tsOptions;
62371
62584
  };
62372
62585
 
62586
+ /**
62587
+ * Create a TypeScript Program ({@link ts.Program}) to perform builds of a Stencil project using the provided
62588
+ * `buildCallback` entity
62589
+ * @param config a Stencil configuration to apply to a full build of a Stencil project
62590
+ * @param buildCallback a callback that invokes the actual transpilation of a Stencil project
62591
+ * @returns a Program that marries the TypeScript and Stencil compilers together.
62592
+ */
62373
62593
  const createTsBuildProgram = async (config, buildCallback) => {
62374
- let isRunning = false;
62375
- let timeoutId;
62594
+ let isBuildRunning = false;
62595
+ let currentBuildTimeoutId;
62376
62596
  const optionsToExtend = getTsOptionsToExtend(config);
62597
+ /**
62598
+ * Create a {@link ts.System}. The System is responsible for handling all interactions between the TypeScript compiler
62599
+ * and the host operating system.
62600
+ */
62377
62601
  const tsWatchSys = {
62378
62602
  ...t.sys,
62379
- watchFile(path, callback) {
62380
- if (path.endsWith(`/${GENERATED_DTS$1}`)) {
62381
- return t.sys.watchFile(path, callback);
62382
- }
62603
+ /**
62604
+ * Watch changes in source files, missing files needed to update the program or config file
62605
+ * @returns a no-op file watcher
62606
+ */
62607
+ watchFile() {
62383
62608
  return {
62384
62609
  close() { },
62385
62610
  };
62386
62611
  },
62612
+ /**
62613
+ * Watch a resolved module's failed lookup locations, config file specs, type roots where auto type reference
62614
+ * directives are added
62615
+ * @returns a no-op file watcher
62616
+ */
62387
62617
  watchDirectory() {
62388
62618
  return {
62389
62619
  close() { },
62390
62620
  };
62391
62621
  },
62392
- setTimeout(callback, time) {
62393
- timeoutId = setInterval(() => {
62394
- if (!isRunning) {
62622
+ /**
62623
+ * Set delayed compilation, so that multiple changes in short span are compiled together
62624
+ * @param callback a callback to invoke upon the completion of compilation. this function is provided to Stencil by
62625
+ * the TypeScript compiler.
62626
+ * @param timeoutMs the minimum time to wait (in milliseconds) before checking if compilation is complete or not
62627
+ * @returns the identifier for the interval that's created
62628
+ */
62629
+ setTimeout(callback, timeoutMs) {
62630
+ currentBuildTimeoutId = setInterval(() => {
62631
+ if (!isBuildRunning) {
62395
62632
  callback();
62396
- clearInterval(timeoutId);
62633
+ clearInterval(currentBuildTimeoutId);
62397
62634
  }
62398
- }, config.sys.watchTimeout || time);
62399
- return timeoutId;
62635
+ }, config.sys.watchTimeout || timeoutMs);
62636
+ return currentBuildTimeoutId;
62400
62637
  },
62401
- clearTimeout(id) {
62402
- return clearInterval(id);
62638
+ /**
62639
+ * Reset existing delayed compilation
62640
+ * @param timeoutId the current build timeout identifier to clear
62641
+ */
62642
+ clearTimeout(timeoutId) {
62643
+ clearInterval(timeoutId);
62403
62644
  },
62404
62645
  };
62405
- config.sys.addDestory(() => tsWatchSys.clearTimeout(timeoutId));
62646
+ config.sys.addDestory(() => tsWatchSys.clearTimeout(currentBuildTimeoutId));
62647
+ /**
62648
+ * Create a {@link ts.WatchCompilerHost}. A CompilerHost allows a {@link ts.Program} to interact with the
62649
+ * {@link ts.System}, by acting as an intermediary:
62650
+ * ```
62651
+ * ┌────────────┐ ┌──────────────────────┐ ┌───────────┐ ┌──────────────────┐
62652
+ * │ ts.Program │<->│ ts.WatchCompilerHost │<->│ ts.System │<->│ Operating System │
62653
+ * └────────────┘ └──────────────────────┘ └───────────┘ └──────────────────┘
62654
+ * ```
62655
+ *
62656
+ * Strictly speaking, the created entity is a subclass of a WatchCompilerHost. The
62657
+ * {@link ts.WatchCompilerHostOfConfigFile} class has the following features that makes it useful to Stencil (even
62658
+ * when Stencil is performing a single, full build):
62659
+ * - it provides the opportunity to extend/alter an existing tsconfig file, allowing users to override specific
62660
+ * configuration options via {@link ts.WatchCompilerHostOfConfigFile#optionsToExtend}, which is a provided as an
62661
+ * argument in the constructor
62662
+ * - it includes the {@link ts.WatchCompilerHost#afterProgramCreate} function in its interface, which Stencil
62663
+ * overrides to invoke a build callback (not as a part of this object's creation)
62664
+ */
62406
62665
  const tsWatchHost = t.createWatchCompilerHost(config.tsconfig, optionsToExtend, tsWatchSys, t.createEmitAndSemanticDiagnosticsBuilderProgram, (reportDiagnostic) => {
62407
62666
  config.logger.debug('watch reportDiagnostic:' + reportDiagnostic.messageText);
62408
62667
  }, (reportWatchStatus) => {
62409
62668
  config.logger.debug(reportWatchStatus.messageText);
62410
62669
  });
62670
+ /**
62671
+ * Override {@link ts.WatchCompilerHost#afterProgramCreate} to invoke the build callback that was provided as an
62672
+ * argument to this function.
62673
+ * @param tsBuilder a {@link ts.BuilderProgram} to manage the {@link ts.Program} in the provided build context
62674
+ */
62411
62675
  tsWatchHost.afterProgramCreate = async (tsBuilder) => {
62412
- isRunning = true;
62676
+ isBuildRunning = true;
62413
62677
  await buildCallback(tsBuilder);
62414
- isRunning = false;
62678
+ isBuildRunning = false;
62415
62679
  };
62680
+ /**
62681
+ * Create the initial {@link ts.Program} using Stencil's custom {@link ts.WatchCompilerHostOfConfigFile}. The Program
62682
+ * represents the _TypeScript_ compiler context, that will work in tandem with Stencil's compiler context and build
62683
+ * context
62684
+ */
62416
62685
  return t.createWatchProgram(tsWatchHost);
62417
62686
  };
62418
62687
 
62688
+ /**
62689
+ * Build a callable function to perform a full build of a Stencil project
62690
+ * @param config a Stencil configuration to apply to a full build of a Stencil project
62691
+ * @param compilerCtx the current Stencil compiler context
62692
+ * @returns the results of a full build of Stencil
62693
+ */
62419
62694
  const createFullBuild = async (config, compilerCtx) => {
62420
62695
  return new Promise((resolve) => {
62421
62696
  let tsWatchProgram = null;
@@ -62423,6 +62698,10 @@ const createFullBuild = async (config, compilerCtx) => {
62423
62698
  config.logger.debug(`fileUpdate: ${p}`);
62424
62699
  compilerCtx.fs.clearFileCache(p);
62425
62700
  });
62701
+ /**
62702
+ * A function that kicks off the transpilation process for both the TypeScript and Stencil compilers
62703
+ * @param tsBuilder the manager of the {@link ts.Program} state
62704
+ */
62426
62705
  const onBuild = async (tsBuilder) => {
62427
62706
  const buildCtx = new BuildContext(config, compilerCtx);
62428
62707
  buildCtx.isRebuild = false;
@@ -63577,6 +63856,11 @@ const patchFs = (userSys) => {
63577
63856
  Object.assign(fsObj.__sys, userSys);
63578
63857
  };
63579
63858
 
63859
+ /**
63860
+ * Generate a Stencil compiler instance
63861
+ * @param config a Stencil configuration to apply to the compiler instance
63862
+ * @returns a new instance of a Stencil compiler
63863
+ */
63580
63864
  const createCompiler = async (config) => {
63581
63865
  // actual compiler code
63582
63866
  // could be in a web worker on the browser
@@ -64257,7 +64541,7 @@ const getComponentPathContent = (componentGraph, outputTarget) => {
64257
64541
  const dependencies = [
64258
64542
  {
64259
64543
  name: "@stencil/core",
64260
- version: "2.15.2",
64544
+ version: "2.16.0",
64261
64545
  main: "compiler/stencil.js",
64262
64546
  resources: [
64263
64547
  "package.json",
@@ -64371,29 +64655,55 @@ const getAbsolutePath = (config, dir) => {
64371
64655
  }
64372
64656
  return dir;
64373
64657
  };
64658
+ /**
64659
+ * This function does two things:
64660
+ *
64661
+ * 1. If you pass a `flagName`, it will hoist that `flagName` out of the
64662
+ * `ConfigFlags` object and onto the 'root' level (if you will) of the
64663
+ * `config` under the `configName` (`keyof d.Config`) that you pass.
64664
+ * 2. If you _don't_ pass a `flagName` it will just set the value you supply
64665
+ * on the config.
64666
+ *
64667
+ * @param config the config that we want to update
64668
+ * @param configName the key we're setting on the config
64669
+ * @param flagName either the name of a ConfigFlag prop we want to hoist up or null
64670
+ * @param defaultValue the default value we should set!
64671
+ */
64374
64672
  const setBooleanConfig = (config, configName, flagName, defaultValue) => {
64673
+ var _a;
64375
64674
  if (flagName) {
64376
- if (typeof config.flags[flagName] === 'boolean') {
64377
- config[configName] = config.flags[flagName];
64675
+ const flagValue = (_a = config.flags) === null || _a === void 0 ? void 0 : _a[flagName];
64676
+ if (isBoolean$1(flagValue)) {
64677
+ config[configName] = flagValue;
64378
64678
  }
64379
64679
  }
64380
64680
  const userConfigName = getUserConfigName(config, configName);
64381
64681
  if (typeof config[userConfigName] === 'function') {
64382
64682
  config[userConfigName] = !!config[userConfigName]();
64383
64683
  }
64384
- if (typeof config[userConfigName] === 'boolean') {
64684
+ if (isBoolean$1(config[userConfigName])) {
64385
64685
  config[configName] = config[userConfigName];
64386
64686
  }
64387
64687
  else {
64388
64688
  config[configName] = defaultValue;
64389
64689
  }
64390
64690
  };
64691
+ /**
64692
+ * Find any possibly mis-capitalized configuration names on the config, logging
64693
+ * and warning if one is found.
64694
+ *
64695
+ * @param config the user-supplied config that we're dealing with
64696
+ * @param correctConfigName the configuration name that we're checking for right now
64697
+ * @returns a string container a mis-capitalized config name found on the
64698
+ * config object, if any.
64699
+ */
64391
64700
  const getUserConfigName = (config, correctConfigName) => {
64701
+ var _a;
64392
64702
  const userConfigNames = Object.keys(config);
64393
64703
  for (const userConfigName of userConfigNames) {
64394
64704
  if (userConfigName.toLowerCase() === correctConfigName.toLowerCase()) {
64395
64705
  if (userConfigName !== correctConfigName) {
64396
- config.logger.warn(`config "${userConfigName}" should be "${correctConfigName}"`);
64706
+ (_a = config.logger) === null || _a === void 0 ? void 0 : _a.warn(`config "${userConfigName}" should be "${correctConfigName}"`);
64397
64707
  return userConfigName;
64398
64708
  }
64399
64709
  break;
@@ -64403,19 +64713,20 @@ const getUserConfigName = (config, correctConfigName) => {
64403
64713
  };
64404
64714
 
64405
64715
  const validateDevServer = (config, diagnostics) => {
64406
- var _a;
64716
+ var _a, _b, _c, _d, _e, _f, _g;
64407
64717
  if ((config.devServer === null || config.devServer) === false) {
64408
- return null;
64718
+ return undefined;
64409
64719
  }
64410
- const flags = config.flags;
64720
+ const flags = (_a = config.flags) !== null && _a !== void 0 ? _a : {};
64411
64721
  const devServer = { ...config.devServer };
64412
- if (isString$1(flags.address)) {
64722
+ if (flags.address && isString$1(flags.address)) {
64413
64723
  devServer.address = flags.address;
64414
64724
  }
64415
64725
  else if (!isString$1(devServer.address)) {
64416
64726
  devServer.address = '0.0.0.0';
64417
64727
  }
64418
- let addressProtocol;
64728
+ // default to http for localdev
64729
+ let addressProtocol = 'http';
64419
64730
  if (devServer.address.toLowerCase().startsWith('http://')) {
64420
64731
  devServer.address = devServer.address.substring(7);
64421
64732
  addressProtocol = 'http';
@@ -64425,8 +64736,13 @@ const validateDevServer = (config, diagnostics) => {
64425
64736
  addressProtocol = 'https';
64426
64737
  }
64427
64738
  devServer.address = devServer.address.split('/')[0];
64428
- let addressPort;
64739
+ // split on `:` to get the domain and the (possibly present) port
64740
+ // separately. we've already sliced off the protocol (if present) above
64741
+ // so we can safely split on `:` here.
64429
64742
  const addressSplit = devServer.address.split(':');
64743
+ const isLocalhost = addressSplit[0] === 'localhost' || !isNaN(addressSplit[0].split('.')[0]);
64744
+ // if localhost we use 3333 as a default port
64745
+ let addressPort = isLocalhost ? 3333 : undefined;
64430
64746
  if (addressSplit.length > 1) {
64431
64747
  if (!isNaN(addressSplit[1])) {
64432
64748
  devServer.address = addressSplit[0];
@@ -64440,12 +64756,6 @@ const validateDevServer = (config, diagnostics) => {
64440
64756
  if (isNumber$1(addressPort)) {
64441
64757
  devServer.port = addressPort;
64442
64758
  }
64443
- else if (devServer.address === 'localhost' || !isNaN(devServer.address.split('.')[0])) {
64444
- devServer.port = 3333;
64445
- }
64446
- else {
64447
- devServer.port = null;
64448
- }
64449
64759
  }
64450
64760
  if (devServer.reloadStrategy === undefined) {
64451
64761
  devServer.reloadStrategy = 'hmr';
@@ -64465,14 +64775,14 @@ const validateDevServer = (config, diagnostics) => {
64465
64775
  if (!isBoolean$1(devServer.websocket)) {
64466
64776
  devServer.websocket = true;
64467
64777
  }
64468
- if ((_a = config === null || config === void 0 ? void 0 : config.flags) === null || _a === void 0 ? void 0 : _a.ssr) {
64778
+ if ((_b = config === null || config === void 0 ? void 0 : config.flags) === null || _b === void 0 ? void 0 : _b.ssr) {
64469
64779
  devServer.ssr = true;
64470
64780
  }
64471
64781
  else {
64472
64782
  devServer.ssr = !!devServer.ssr;
64473
64783
  }
64474
64784
  if (devServer.ssr) {
64475
- const wwwOutput = config.outputTargets.find(isOutputTargetWww);
64785
+ const wwwOutput = ((_c = config.outputTargets) !== null && _c !== void 0 ? _c : []).find(isOutputTargetWww);
64476
64786
  devServer.prerenderConfig = wwwOutput === null || wwwOutput === void 0 ? void 0 : wwwOutput.prerenderConfig;
64477
64787
  }
64478
64788
  if (isString$1(config.srcIndexHtml)) {
@@ -64496,16 +64806,17 @@ const validateDevServer = (config, diagnostics) => {
64496
64806
  else if (flags.prerender && !config.watch) {
64497
64807
  devServer.openBrowser = false;
64498
64808
  }
64499
- let serveDir = null;
64500
- let basePath = null;
64501
- const wwwOutputTarget = config.outputTargets.find(isOutputTargetWww);
64809
+ let serveDir;
64810
+ let basePath;
64811
+ const wwwOutputTarget = ((_d = config.outputTargets) !== null && _d !== void 0 ? _d : []).find(isOutputTargetWww);
64502
64812
  if (wwwOutputTarget) {
64503
- const baseUrl = new URL(wwwOutputTarget.baseUrl, 'http://config.stenciljs.com');
64813
+ const baseUrl = new URL((_e = wwwOutputTarget.baseUrl) !== null && _e !== void 0 ? _e : '', 'http://config.stenciljs.com');
64504
64814
  basePath = baseUrl.pathname;
64505
- serveDir = wwwOutputTarget.appDir;
64815
+ serveDir = (_f = wwwOutputTarget.appDir) !== null && _f !== void 0 ? _f : '';
64506
64816
  }
64507
64817
  else {
64508
- serveDir = config.rootDir;
64818
+ basePath = '';
64819
+ serveDir = (_g = config.rootDir) !== null && _g !== void 0 ? _g : '';
64509
64820
  }
64510
64821
  if (!isString$1(basePath) || basePath.trim() === '') {
64511
64822
  basePath = `/`;
@@ -64587,7 +64898,8 @@ const validateNamespace = (c, diagnostics) => {
64587
64898
  }
64588
64899
  };
64589
64900
  const validateDistNamespace = (config, diagnostics) => {
64590
- const hasDist = config.outputTargets.some(isOutputTargetDist);
64901
+ var _a;
64902
+ const hasDist = ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : []).some(isOutputTargetDist);
64591
64903
  if (hasDist) {
64592
64904
  if (!isString$1(config.namespace) || config.namespace.toLowerCase() === 'app') {
64593
64905
  const err = buildError(diagnostics);
@@ -64597,10 +64909,25 @@ const validateDistNamespace = (config, diagnostics) => {
64597
64909
  };
64598
64910
  const DEFAULT_NAMESPACE = 'App';
64599
64911
 
64912
+ /**
64913
+ * Check the provided `.hydratedFlag` prop and return a properly-validated value.
64914
+ *
64915
+ * @param config the configuration we're examining
64916
+ * @returns a suitable value for the hydratedFlag property
64917
+ */
64600
64918
  const validateHydrated = (config) => {
64919
+ /**
64920
+ * If `config.hydratedFlag` is set to `null` that is an explicit signal that we
64921
+ * should _not_ create a default configuration when validating and should instead
64922
+ * just return `undefined`.
64923
+ *
64924
+ * See {@link HydratedFlag} for more details.
64925
+ */
64601
64926
  if (config.hydratedFlag === null || config.hydratedFlag === false) {
64602
- return null;
64927
+ return undefined;
64603
64928
  }
64929
+ // Here we start building up a default config since `.hydratedFlag` wasn't set to
64930
+ // `null` on the provided config.
64604
64931
  const hydratedFlag = { ...config.hydratedFlag };
64605
64932
  if (!isString$1(hydratedFlag.name) || hydratedFlag.property === '') {
64606
64933
  hydratedFlag.name = `hydrated`;
@@ -65237,9 +65564,9 @@ const validateCustomElementBundle = (config, userOutputs) => {
65237
65564
  const validateOutputTargets = (config, diagnostics) => {
65238
65565
  const userOutputs = (config.outputTargets || []).slice();
65239
65566
  userOutputs.forEach((outputTarget) => {
65240
- if (!VALID_TYPES.includes(outputTarget.type)) {
65567
+ if (!isValidConfigOutputTarget(outputTarget.type)) {
65241
65568
  const err = buildError(diagnostics);
65242
- err.messageText = `Invalid outputTarget type "${outputTarget.type}". Valid outputTarget types include: ${VALID_TYPES.map((t) => `"${t}"`).join(', ')}`;
65569
+ err.messageText = `Invalid outputTarget type "${outputTarget.type}". Valid outputTarget types include: ${VALID_CONFIG_OUTPUT_TARGETS.map((t) => `"${t}"`).join(', ')}`;
65243
65570
  }
65244
65571
  else if (outputTarget.type === DIST_CUSTOM_ELEMENTS_BUNDLE) {
65245
65572
  // TODO(STENCIL-260): Remove this check when the 'dist-custom-elements-bundle' is removed
@@ -65375,6 +65702,7 @@ const DEFAULT_ROLLUP_CONFIG = {
65375
65702
  };
65376
65703
 
65377
65704
  const validateTesting = (config, diagnostics) => {
65705
+ var _a;
65378
65706
  const testing = (config.testing = Object.assign({}, config.testing || {}));
65379
65707
  if (!config.flags || (!config.flags.e2e && !config.flags.spec)) {
65380
65708
  return;
@@ -65429,10 +65757,11 @@ const validateTesting = (config, diagnostics) => {
65429
65757
  testing.testPathIgnorePatterns = DEFAULT_IGNORE_PATTERNS.map((ignorePattern) => {
65430
65758
  return join(testing.rootDir, ignorePattern);
65431
65759
  });
65432
- config.outputTargets
65760
+ ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : [])
65433
65761
  .filter((o) => (isOutputTargetDist(o) || isOutputTargetWww(o)) && o.dir)
65434
65762
  .forEach((outputTarget) => {
65435
- testing.testPathIgnorePatterns.push(outputTarget.dir);
65763
+ var _a;
65764
+ (_a = testing.testPathIgnorePatterns) === null || _a === void 0 ? void 0 : _a.push(outputTarget.dir);
65436
65765
  });
65437
65766
  }
65438
65767
  if (typeof testing.preset !== 'string') {
@@ -65549,7 +65878,15 @@ const validateWorkers = (config) => {
65549
65878
  }
65550
65879
  };
65551
65880
 
65552
- const validateConfig = (userConfig) => {
65881
+ /**
65882
+ * Validate a Config object, ensuring that all its field are present and
65883
+ * consistent with our expectations. This function transforms an
65884
+ * `UnvalidatedConfig` to a `Config`.
65885
+ *
65886
+ * @param userConfig an unvalidated config that we've gotten from a user
65887
+ * @returns an object with config and diagnostics props
65888
+ */
65889
+ const validateConfig = (userConfig = {}) => {
65553
65890
  const config = Object.assign({}, userConfig || {}); // not positive it's json safe
65554
65891
  const diagnostics = [];
65555
65892
  // copy flags (we know it'll be json safe)
@@ -65582,7 +65919,7 @@ const validateConfig = (userConfig) => {
65582
65919
  setBooleanConfig(config, 'sourceMap', null, typeof config.sourceMap === 'undefined' ? false : config.sourceMap);
65583
65920
  setBooleanConfig(config, 'watch', 'watch', false);
65584
65921
  setBooleanConfig(config, 'buildDocs', 'docs', !config.devMode);
65585
- setBooleanConfig(config, 'buildDist', 'esm', !config.devMode || config.buildEs5);
65922
+ setBooleanConfig(config, 'buildDist', null, !config.devMode || config.buildEs5);
65586
65923
  setBooleanConfig(config, 'profile', 'profile', config.devMode);
65587
65924
  setBooleanConfig(config, 'writeLog', 'log', false);
65588
65925
  setBooleanConfig(config, 'buildAppCore', null, true);