@stencil/core 2.16.1 → 2.17.2-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 (50) hide show
  1. package/cli/config-flags.d.ts +110 -0
  2. package/cli/index.cjs +710 -225
  3. package/cli/index.d.ts +2 -1
  4. package/cli/index.js +710 -225
  5. package/cli/package.json +1 -1
  6. package/compiler/package.json +1 -1
  7. package/compiler/stencil.js +905 -290
  8. package/compiler/stencil.min.js +2 -2
  9. package/dependencies.json +1 -1
  10. package/dev-server/client/index.js +1 -1
  11. package/dev-server/client/package.json +1 -1
  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 +2 -2
  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 -6
  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 +1 -1
  24. package/internal/hydrate/index.js +2 -2
  25. package/internal/hydrate/package.json +1 -1
  26. package/internal/package.json +1 -1
  27. package/internal/stencil-private.d.ts +6 -2
  28. package/internal/stencil-public-compiler.d.ts +67 -48
  29. package/internal/testing/index.js +1 -1
  30. package/internal/testing/package.json +1 -1
  31. package/mock-doc/index.cjs +163 -5
  32. package/mock-doc/index.d.ts +86 -1
  33. package/mock-doc/index.js +163 -5
  34. package/mock-doc/package.json +1 -1
  35. package/package.json +2 -1
  36. package/screenshot/package.json +1 -1
  37. package/sys/node/index.js +325 -314
  38. package/sys/node/package.json +1 -1
  39. package/sys/node/worker.js +1 -1
  40. package/testing/index.d.ts +1 -1
  41. package/testing/index.js +445 -382
  42. package/testing/jest/jest-config.d.ts +1 -1
  43. package/testing/jest/jest-runner.d.ts +3 -2
  44. package/testing/jest/jest-screenshot.d.ts +1 -1
  45. package/testing/mocks.d.ts +48 -3
  46. package/testing/package.json +1 -1
  47. package/testing/puppeteer/puppeteer-browser.d.ts +2 -2
  48. package/testing/test/testing-utils.spec.d.ts +1 -0
  49. package/testing/testing-utils.d.ts +74 -2
  50. package/testing/testing.d.ts +2 -2
@@ -1,5 +1,5 @@
1
1
  /*!
2
- Stencil Compiler v2.16.1 | MIT Licensed | https://stenciljs.com
2
+ Stencil Compiler v2.17.2-0 | MIT Licensed | https://stenciljs.com
3
3
  */
4
4
  (function(exports) {
5
5
  'use strict';
@@ -727,12 +727,27 @@ const trimFalsy = (data) => {
727
727
  return arr;
728
728
  };
729
729
 
730
- const toLowerCase = (str) => str.toLowerCase();
731
- const toDashCase = (str) => toLowerCase(str
732
- .replace(/([A-Z0-9])/g, (g) => ' ' + g[0])
730
+ /**
731
+ * Convert a string from PascalCase to dash-case
732
+ *
733
+ * @param str the string to convert
734
+ * @returns a converted string
735
+ */
736
+ const toDashCase = (str) => str
737
+ .replace(/([A-Z0-9])/g, (match) => ` ${match[0]}`)
733
738
  .trim()
734
- .replace(/ /g, '-'));
735
- const dashToPascalCase$1 = (str) => toLowerCase(str)
739
+ .split(' ')
740
+ .join('-')
741
+ .toLowerCase();
742
+ /**
743
+ * Convert a string from dash-case / kebab-case to PascalCase (or CamelCase,
744
+ * or whatever you call it!)
745
+ *
746
+ * @param str a string to convert
747
+ * @returns a converted string
748
+ */
749
+ const dashToPascalCase$1 = (str) => str
750
+ .toLowerCase()
736
751
  .split('-')
737
752
  .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
738
753
  .join('');
@@ -789,8 +804,8 @@ const pluck = (obj, keys) => {
789
804
  return final;
790
805
  }, {});
791
806
  };
792
- const isBoolean$1 = (v) => typeof v === 'boolean';
793
807
  const isDefined = (v) => v !== null && v !== undefined;
808
+ const isBoolean$1 = (v) => typeof v === 'boolean';
794
809
  const isFunction = (v) => typeof v === 'function';
795
810
  const isNumber$1 = (v) => typeof v === 'number';
796
811
  const isObject$4 = (val) => val != null && typeof val === 'object' && Array.isArray(val) === false;
@@ -1631,7 +1646,7 @@ const isDtsFile$1 = (filePath) => {
1631
1646
  /**
1632
1647
  * Generate the preamble to be placed atop the main file of the build
1633
1648
  * @param config the Stencil configuration file
1634
- * @return the generated preamble
1649
+ * @returns the generated preamble
1635
1650
  */
1636
1651
  const generatePreamble = (config) => {
1637
1652
  const { preamble } = config;
@@ -1697,38 +1712,30 @@ const readPackageJson = async (config, compilerCtx, buildCtx) => {
1697
1712
  }
1698
1713
  }
1699
1714
  };
1715
+ /**
1716
+ * Parse a string read from a `package.json` file
1717
+ * @param pkgJsonStr the string read from a `package.json` file
1718
+ * @param pkgJsonFilePath the path to the already read `package.json` file
1719
+ * @returns the results of parsing the provided contents of the `package.json` file
1720
+ */
1700
1721
  const parsePackageJson = (pkgJsonStr, pkgJsonFilePath) => {
1701
- if (isString$1(pkgJsonFilePath)) {
1702
- return parseJson(pkgJsonStr, pkgJsonFilePath);
1703
- }
1704
- return null;
1705
- };
1706
- const parseJson = (jsonStr, filePath) => {
1707
- const rtn = {
1722
+ const parseResult = {
1708
1723
  diagnostic: null,
1709
1724
  data: null,
1710
- filePath,
1725
+ filePath: pkgJsonFilePath,
1711
1726
  };
1712
- if (isString$1(jsonStr)) {
1713
- try {
1714
- rtn.data = JSON.parse(jsonStr);
1715
- }
1716
- catch (e) {
1717
- rtn.diagnostic = buildError();
1718
- rtn.diagnostic.absFilePath = filePath;
1719
- rtn.diagnostic.header = `Error Parsing JSON`;
1720
- if (e instanceof Error) {
1721
- rtn.diagnostic.messageText = e.message;
1722
- }
1723
- }
1727
+ try {
1728
+ parseResult.data = JSON.parse(pkgJsonStr);
1724
1729
  }
1725
- else {
1726
- rtn.diagnostic = buildError();
1727
- rtn.diagnostic.absFilePath = filePath;
1728
- rtn.diagnostic.header = `Error Parsing JSON`;
1729
- rtn.diagnostic.messageText = `Invalid JSON input to parse`;
1730
+ catch (e) {
1731
+ parseResult.diagnostic = buildError();
1732
+ parseResult.diagnostic.absFilePath = isString$1(pkgJsonFilePath) ? pkgJsonFilePath : undefined;
1733
+ parseResult.diagnostic.header = `Error Parsing JSON`;
1734
+ if (e instanceof Error) {
1735
+ parseResult.diagnostic.messageText = e.message;
1736
+ }
1730
1737
  }
1731
- return rtn;
1738
+ return parseResult;
1732
1739
  };
1733
1740
  const SKIP_DEPS = ['@stencil/core'];
1734
1741
 
@@ -2034,10 +2041,14 @@ const buildEvents = () => {
2034
2041
  };
2035
2042
  };
2036
2043
 
2044
+ /**
2045
+ * Creates an instance of a logger
2046
+ * @returns the new logger instance
2047
+ */
2037
2048
  const createLogger = () => {
2038
2049
  let useColors = IS_BROWSER_ENV;
2039
2050
  let level = 'info';
2040
- const logger = {
2051
+ return {
2041
2052
  enableColors: (uc) => (useColors = uc),
2042
2053
  getLevel: () => level,
2043
2054
  setLevel: (l) => (level = l),
@@ -2064,7 +2075,6 @@ const createLogger = () => {
2064
2075
  diagnostics.forEach((diagnostic) => logDiagnostic(diagnostic, useColors));
2065
2076
  },
2066
2077
  };
2067
- return logger;
2068
2078
  };
2069
2079
  const logDiagnostic = (diagnostic, useColors) => {
2070
2080
  let color = BLUE;
@@ -2354,8 +2364,16 @@ const getPackageDirPath = (p, moduleId) => {
2354
2364
  return null;
2355
2365
  };
2356
2366
 
2367
+ /**
2368
+ * A fetch wrapper which dispatches to `sys.fetch` if present, and otherwise
2369
+ * uses `global.fetch`.
2370
+ *
2371
+ * @param sys a compiler system object
2372
+ * @param input a `RequestInfo` object
2373
+ * @param init an optional `RequestInit` object
2374
+ * @returns a Promise wrapping a response
2375
+ */
2357
2376
  const httpFetch = (sys, input, init) => {
2358
- console.trace(input);
2359
2377
  if (sys && isFunction(sys.fetch)) {
2360
2378
  return sys.fetch(input, init);
2361
2379
  }
@@ -2363,10 +2381,16 @@ const httpFetch = (sys, input, init) => {
2363
2381
  };
2364
2382
  const packageVersions = new Map();
2365
2383
  const known404Urls = new Set();
2366
- const getStencilRootUrl = (compilerExe) => new URL('../', compilerExe).href;
2367
- const getStencilModuleUrl = (compilerExe, p) => {
2368
- p = normalizePath$1(p);
2369
- let parts = p.split('/');
2384
+ /**
2385
+ * Get the URL for a Stencil module given the path to the compiler
2386
+ *
2387
+ * @param compilerExe the path to the compiler executable
2388
+ * @param path the path to the module or file in question
2389
+ * @returns a URL for the file of interest
2390
+ */
2391
+ const getStencilModuleUrl = (compilerExe, path) => {
2392
+ path = normalizePath$1(path);
2393
+ let parts = path.split('/');
2370
2394
  const nmIndex = parts.lastIndexOf('node_modules');
2371
2395
  if (nmIndex > -1 && nmIndex < parts.length - 1) {
2372
2396
  parts = parts.slice(nmIndex + 1);
@@ -2376,9 +2400,10 @@ const getStencilModuleUrl = (compilerExe, p) => {
2376
2400
  else {
2377
2401
  parts = parts.slice(1);
2378
2402
  }
2379
- p = parts.join('/');
2403
+ path = parts.join('/');
2380
2404
  }
2381
- return new URL('./' + p, getStencilRootUrl(compilerExe)).href;
2405
+ const stencilRootUrl = new URL('../', compilerExe).href;
2406
+ return new URL('./' + path, stencilRootUrl).href;
2382
2407
  };
2383
2408
  const getCommonDirUrl = (sys, pkgVersions, dirPath, fileName) => getNodeModuleFetchUrl(sys, pkgVersions, dirPath) + '/' + fileName;
2384
2409
  const getNodeModuleFetchUrl = (sys, pkgVersions, filePath) => {
@@ -4027,7 +4052,7 @@ const createCustomResolverAsync = (sys, inMemoryFs, exts) => {
4027
4052
  };
4028
4053
  };
4029
4054
 
4030
- const buildId = '20220603123838';
4055
+ const buildId = '20220719192625';
4031
4056
  const minfyJsId = 'terser5.6.1_7';
4032
4057
  const optimizeCssId = 'autoprefixer10.2.5_postcss8.2.13_7';
4033
4058
  const parse5Version = '6.0.1';
@@ -4035,8 +4060,8 @@ const rollupVersion = '2.42.3';
4035
4060
  const sizzleVersion = '2.42.3';
4036
4061
  const terserVersion = '5.6.1';
4037
4062
  const typescriptVersion = '4.5.4';
4038
- const vermoji = '🎻';
4039
- const version$3 = '2.16.1';
4063
+ const vermoji = '🏜';
4064
+ const version$3 = '2.17.2-0';
4040
4065
  const versions = {
4041
4066
  stencil: version$3,
4042
4067
  parse5: parse5Version,
@@ -4585,6 +4610,17 @@ const createSystem = (c) => {
4585
4610
  };
4586
4611
 
4587
4612
  let cssProcessor;
4613
+ /**
4614
+ * Autoprefix a CSS string, adding vendor prefixes to make sure that what
4615
+ * is written in the CSS will render correctly in our range of supported browsers.
4616
+ * This function uses PostCSS in compbination with the Autoprefix plugin to
4617
+ * automatically add vendor prefixes based on a list of browsers which we want
4618
+ * to support.
4619
+ *
4620
+ * @param cssText the text to be prefixed
4621
+ * @param opts an optional param with options for Autoprefixer
4622
+ * @returns a Promise wrapping some prefixed CSS as well as diagnostics
4623
+ */
4588
4624
  const autoprefixCss = async (cssText, opts) => {
4589
4625
  const output = {
4590
4626
  output: cssText,
@@ -4594,7 +4630,7 @@ const autoprefixCss = async (cssText, opts) => {
4594
4630
  return output;
4595
4631
  }
4596
4632
  try {
4597
- const autoprefixerOpts = opts != null && typeof opts === 'object' ? opts : DEFAULT_AUTOPREFIX_LEGACY;
4633
+ const autoprefixerOpts = opts != null && typeof opts === 'object' ? opts : DEFAULT_AUTOPREFIX_OPTIONS;
4598
4634
  const processor = getProcessor(autoprefixerOpts);
4599
4635
  const result = await processor.process(cssText, { map: null });
4600
4636
  result.warnings().forEach((warning) => {
@@ -4650,6 +4686,12 @@ const autoprefixCss = async (cssText, opts) => {
4650
4686
  }
4651
4687
  return output;
4652
4688
  };
4689
+ /**
4690
+ * Get the processor for PostCSS and the Autoprefixer plugin
4691
+ *
4692
+ * @param autoprefixerOpts Options for Autoprefixer
4693
+ * @returns postCSS with the Autoprefixer plugin applied
4694
+ */
4653
4695
  const getProcessor = (autoprefixerOpts) => {
4654
4696
  const { postcss, autoprefixer } = requireFunc('../sys/node/autoprefixer.js');
4655
4697
  if (!cssProcessor) {
@@ -4657,7 +4699,19 @@ const getProcessor = (autoprefixerOpts) => {
4657
4699
  }
4658
4700
  return cssProcessor;
4659
4701
  };
4660
- const DEFAULT_AUTOPREFIX_LEGACY = {
4702
+ /**
4703
+ * Default options for the Autoprefixer PostCSS plugin. See the documentation:
4704
+ * https://github.com/postcss/autoprefixer#options for a complete list.
4705
+ *
4706
+ * This default option set will:
4707
+ *
4708
+ * - override the default browser list (`overrideBrowserslist`)
4709
+ * - turn off the visual cascade (`cascade`)
4710
+ * - disable auto-removing outdated prefixes (`remove`)
4711
+ * - set `flexbox` to `"no-2009"`, which limits prefixing for flexbox to the
4712
+ * final and IE 10 versions of the specification
4713
+ */
4714
+ const DEFAULT_AUTOPREFIX_OPTIONS = {
4661
4715
  overrideBrowserslist: ['last 2 versions', 'iOS >= 9', 'Android >= 4.4', 'Explorer >= 11', 'ExplorerMobile >= 11'],
4662
4716
  cascade: false,
4663
4717
  remove: false,
@@ -5453,6 +5507,13 @@ const resolveStylesheetUrl = async (nodes, resolveUrl, resolved) => {
5453
5507
  }
5454
5508
  };
5455
5509
 
5510
+ /**
5511
+ * Optimize a CSS file, optionally running an autoprefixer and a minifier
5512
+ * depending on the options set on the input options argument.
5513
+ *
5514
+ * @param inputOpts input CSS options
5515
+ * @returns a promise wrapping the optimized output
5516
+ */
5456
5517
  const optimizeCss$1 = async (inputOpts) => {
5457
5518
  let result = {
5458
5519
  output: inputOpts.input,
@@ -10986,6 +11047,16 @@ MagicString$2.prototype.trimStart = function trimStart (charType) {
10986
11047
  return this;
10987
11048
  };
10988
11049
 
11050
+ /**
11051
+ * Parse CSS docstrings that Stencil supports, as documented here:
11052
+ * https://stenciljs.com/docs/docs-json#css-variables
11053
+ *
11054
+ * Docstrings found in the supplied style text will be added to the
11055
+ * `styleDocs` param
11056
+ *
11057
+ * @param styleDocs the array to hold formatted CSS docstrings
11058
+ * @param styleText the CSS text we're working with
11059
+ */
10989
11060
  function parseStyleDocs(styleDocs, styleText) {
10990
11061
  if (typeof styleText !== 'string') {
10991
11062
  return;
@@ -11002,10 +11073,18 @@ function parseStyleDocs(styleDocs, styleText) {
11002
11073
  styleText = styleText.substring(endIndex + CSS_DOC_END.length);
11003
11074
  }
11004
11075
  }
11076
+ /**
11077
+ * Parse a CSS comment string and insert it into the provided array of
11078
+ * style docstrings.
11079
+ *
11080
+ * @param styleDocs an array which will be modified with the docstring
11081
+ * @param comment the comment string
11082
+ */
11005
11083
  function parseCssComment(styleDocs, comment) {
11006
11084
  /**
11007
11085
  * @prop --max-width: Max width of the alert
11008
11086
  */
11087
+ // (the above is an example of what these comments might look like)
11009
11088
  const lines = comment.split(/\r?\n/).map((line) => {
11010
11089
  line = line.trim();
11011
11090
  while (line.startsWith('*')) {
@@ -11033,11 +11112,19 @@ function parseCssComment(styleDocs, comment) {
11033
11112
  styleDocs.push(cssDoc);
11034
11113
  }
11035
11114
  });
11036
- return styleDocs;
11037
11115
  }
11038
- const CSS_DOC_START = `/**`;
11039
- const CSS_DOC_END = `*/`;
11040
- const CSS_PROP_ANNOTATION = `@prop`;
11116
+ /**
11117
+ * Opening syntax for a CSS docstring
11118
+ */
11119
+ const CSS_DOC_START = '/**';
11120
+ /**
11121
+ * Closing syntax for a CSS docstring
11122
+ */
11123
+ const CSS_DOC_END = '*/';
11124
+ /**
11125
+ * The `@prop` annotation we support within CSS docstrings
11126
+ */
11127
+ const CSS_PROP_ANNOTATION = '@prop';
11041
11128
 
11042
11129
  /**
11043
11130
  * @license
@@ -11490,6 +11577,12 @@ const parseImportPath = (importPath) => {
11490
11577
  return parsedPath;
11491
11578
  };
11492
11579
 
11580
+ /**
11581
+ * Strip out comments from some CSS
11582
+ *
11583
+ * @param input the string we'd like to de-comment
11584
+ * @returns de-commented CSS!
11585
+ */
11493
11586
  const stripCssComments = (input) => {
11494
11587
  let isInsideString = null;
11495
11588
  let currentCharacter = '';
@@ -11526,6 +11619,53 @@ const stripCssComments = (input) => {
11526
11619
  return returnValue;
11527
11620
  };
11528
11621
 
11622
+ /**
11623
+ * A regular expression for matching CSS import statements
11624
+ *
11625
+ * According to https://developer.mozilla.org/en-US/docs/Web/CSS/@import
11626
+ * the formal grammar for CSS import statements is:
11627
+ *
11628
+ * ```
11629
+ * @import [ <url> | <string> ]
11630
+ * [ supports( [ <supports-condition> | <declaration> ] ) ]?
11631
+ * <media-query-list>? ;
11632
+ * ```
11633
+ *
11634
+ * Thus the string literal `"@import"` will be followed by a `<url>` or a
11635
+ * `<string>`, where a `<url>` may be a relative or absolute URL _or_ a `url()`
11636
+ * function.
11637
+ *
11638
+ * Thus the regular expression needs to match:
11639
+ *
11640
+ * - the string `"@import
11641
+ * - any amount of whitespace
11642
+ * - a URL, comprised of:
11643
+ * - an optional `url(` function opener
11644
+ * - a non-greedy match on any characters (to match the argument to the URL
11645
+ * function)
11646
+ * - an optional `)` closing paren on the `url()` function
11647
+ * - trailing characters after the URL, given by anything which doesn't match
11648
+ * the line-terminator `;`
11649
+ * - this can match media queries, support conditions, and so on
11650
+ * - a line-terminating semicolon
11651
+ *
11652
+ * The regex has 4 capture groups:
11653
+ *
11654
+ * 1. `@import`
11655
+ * 2. `url(`
11656
+ * 3. characters after `url(`
11657
+ * 4. all characters other than `;`, greedily matching
11658
+ *
11659
+ * We typically only care about group 4 here.
11660
+ */
11661
+ const CSS_IMPORT_RE = /(@import)\s+(url\()?\s?(.*?)\s?\)?([^;]*);?/gi;
11662
+ /**
11663
+ * Our main entry point to this module. This performs an async transformation
11664
+ * of CSS input to ESM.
11665
+ *
11666
+ * @param input CSS input to be transformed to ESM
11667
+ * @returns a promise wrapping transformed ESM output
11668
+ */
11529
11669
  const transformCssToEsm = async (input) => {
11530
11670
  const results = transformCssToEsmModule(input);
11531
11671
  const optimizeResults = await optimizeCss$1({
@@ -11542,10 +11682,22 @@ const transformCssToEsm = async (input) => {
11542
11682
  results.styleText = optimizeResults.output;
11543
11683
  return generateTransformCssToEsm(input, results);
11544
11684
  };
11685
+ /**
11686
+ * A sync function for transforming input CSS to ESM
11687
+ *
11688
+ * @param input the input CSS we're going to transform
11689
+ * @returns transformed ESM output
11690
+ */
11545
11691
  const transformCssToEsmSync = (input) => {
11546
11692
  const results = transformCssToEsmModule(input);
11547
11693
  return generateTransformCssToEsm(input, results);
11548
11694
  };
11695
+ /**
11696
+ * Performs the actual transformation from CSS to ESM
11697
+ *
11698
+ * @param input input CSS to be transformed
11699
+ * @returns ESM output
11700
+ */
11549
11701
  const transformCssToEsmModule = (input) => {
11550
11702
  const results = {
11551
11703
  styleText: input.input,
@@ -11590,6 +11742,14 @@ const transformCssToEsmModule = (input) => {
11590
11742
  }
11591
11743
  return results;
11592
11744
  };
11745
+ /**
11746
+ * Updated the `output` property on `results` with appropriate import statements for
11747
+ * the CSS import tree and the module type.
11748
+ *
11749
+ * @param input the CSS to ESM transform input
11750
+ * @param results the corresponding output
11751
+ * @returns the modified ESM output
11752
+ */
11593
11753
  const generateTransformCssToEsm = (input, results) => {
11594
11754
  const s = new MagicString$2('');
11595
11755
  if (input.module === 'cjs') {
@@ -11619,6 +11779,15 @@ const generateTransformCssToEsm = (input, results) => {
11619
11779
  results.output = s.toString();
11620
11780
  return results;
11621
11781
  };
11782
+ /**
11783
+ * Get all of the CSS imports in a file
11784
+ *
11785
+ * @param varNames a set into which new names will be added
11786
+ * @param cssText the CSS text in question
11787
+ * @param filePath the file path to the file in question
11788
+ * @param modeName the current mode name
11789
+ * @returns an array of import objects
11790
+ */
11622
11791
  const getCssToEsmImports = (varNames, cssText, filePath, modeName) => {
11623
11792
  const cssImports = [];
11624
11793
  if (!cssText.includes('@import')) {
@@ -11660,10 +11829,22 @@ const getCssToEsmImports = (varNames, cssText, filePath, modeName) => {
11660
11829
  }
11661
11830
  return cssImports;
11662
11831
  };
11663
- const CSS_IMPORT_RE = /(@import)\s+(url\()?\s?(.*?)\s?\)?([^;]*);?/gi;
11832
+ /**
11833
+ * Check if a module URL is a css node module
11834
+ *
11835
+ * @param url to check
11836
+ * @returns whether or not it's a Css node module
11837
+ */
11664
11838
  const isCssNodeModule$1 = (url) => {
11665
11839
  return url.startsWith('~');
11666
11840
  };
11841
+ /**
11842
+ * Check if a given import is a local import or not (i.e. check that it
11843
+ * is not importing from some other domain)
11844
+ *
11845
+ * @param srcImport the import to check
11846
+ * @returns whether it's local or not
11847
+ */
11667
11848
  const isLocalCssImport$1 = (srcImport) => {
11668
11849
  srcImport = srcImport.toLowerCase();
11669
11850
  if (srcImport.includes('url(')) {
@@ -11676,6 +11857,13 @@ const isLocalCssImport$1 = (srcImport) => {
11676
11857
  }
11677
11858
  return true;
11678
11859
  };
11860
+ /**
11861
+ * Given a file path and a mode name, create an appropriate variable name
11862
+ *
11863
+ * @param filePath the path we want to use
11864
+ * @param modeName the name for the current style mode (i.e. `md` or `ios` on Ionic)
11865
+ * @returns an appropriate Css var name
11866
+ */
11679
11867
  const createCssVarName = (filePath, modeName) => {
11680
11868
  let varName = path$5.basename(filePath);
11681
11869
  if (modeName && modeName !== DEFAULT_STYLE_MODE && !varName.includes(modeName)) {
@@ -14751,6 +14939,25 @@ class MockMouseEvent extends MockEvent {
14751
14939
  }
14752
14940
  }
14753
14941
  }
14942
+ class MockUIEvent extends MockEvent {
14943
+ constructor(type, uiEventInitDic) {
14944
+ super(type);
14945
+ this.detail = null;
14946
+ this.view = null;
14947
+ if (uiEventInitDic != null) {
14948
+ Object.assign(this, uiEventInitDic);
14949
+ }
14950
+ }
14951
+ }
14952
+ class MockFocusEvent extends MockUIEvent {
14953
+ constructor(type, focusEventInitDic) {
14954
+ super(type);
14955
+ this.relatedTarget = null;
14956
+ if (focusEventInitDic != null) {
14957
+ Object.assign(this, focusEventInitDic);
14958
+ }
14959
+ }
14960
+ }
14754
14961
  class MockEventListener {
14755
14962
  constructor(type, handler) {
14756
14963
  this.type = type;
@@ -15663,6 +15870,9 @@ class MockElement extends MockNode {
15663
15870
  this.shadowRoot = shadowRoot;
15664
15871
  return shadowRoot;
15665
15872
  }
15873
+ blur() {
15874
+ dispatchEvent(this, new MockFocusEvent('blur', { relatedTarget: null, bubbles: true, cancelable: true, composed: true }));
15875
+ }
15666
15876
  get shadowRoot() {
15667
15877
  return this.__shadowRoot || null;
15668
15878
  }
@@ -15731,6 +15941,9 @@ class MockElement extends MockNode {
15731
15941
  get firstElementChild() {
15732
15942
  return this.children[0] || null;
15733
15943
  }
15944
+ focus(_options) {
15945
+ dispatchEvent(this, new MockFocusEvent('focus', { relatedTarget: null, bubbles: true, cancelable: true, composed: true }));
15946
+ }
15734
15947
  getAttribute(attrName) {
15735
15948
  if (attrName === 'style') {
15736
15949
  if (this.__style != null && this.__style.length > 0) {
@@ -16634,7 +16847,28 @@ function createElementNS(ownerDocument, namespaceURI, tagName) {
16634
16847
  return createElement(ownerDocument, tagName);
16635
16848
  }
16636
16849
  else if (namespaceURI === 'http://www.w3.org/2000/svg') {
16637
- return new MockSVGElement(ownerDocument, tagName);
16850
+ switch (tagName.toLowerCase()) {
16851
+ case 'text':
16852
+ case 'tspan':
16853
+ case 'tref':
16854
+ case 'altglyph':
16855
+ case 'textpath':
16856
+ return new MockSVGTextContentElement(ownerDocument, tagName);
16857
+ case 'circle':
16858
+ case 'ellipse':
16859
+ case 'image':
16860
+ case 'line':
16861
+ case 'path':
16862
+ case 'polygon':
16863
+ case 'polyline':
16864
+ case 'rect':
16865
+ case 'use':
16866
+ return new MockSVGGraphicsElement(ownerDocument, tagName);
16867
+ case 'svg':
16868
+ return new MockSVGSVGElement(ownerDocument, tagName);
16869
+ default:
16870
+ return new MockSVGElement(ownerDocument, tagName);
16871
+ }
16638
16872
  }
16639
16873
  else {
16640
16874
  return new MockElement(ownerDocument, tagName);
@@ -16781,6 +17015,98 @@ class MockScriptElement extends MockHTMLElement {
16781
17015
  patchPropAttributes(MockScriptElement.prototype, {
16782
17016
  type: String,
16783
17017
  });
17018
+ class MockDOMMatrix {
17019
+ constructor() {
17020
+ this.a = 1;
17021
+ this.b = 0;
17022
+ this.c = 0;
17023
+ this.d = 1;
17024
+ this.e = 0;
17025
+ this.f = 0;
17026
+ this.m11 = 1;
17027
+ this.m12 = 0;
17028
+ this.m13 = 0;
17029
+ this.m14 = 0;
17030
+ this.m21 = 0;
17031
+ this.m22 = 1;
17032
+ this.m23 = 0;
17033
+ this.m24 = 0;
17034
+ this.m31 = 0;
17035
+ this.m32 = 0;
17036
+ this.m33 = 1;
17037
+ this.m34 = 0;
17038
+ this.m41 = 0;
17039
+ this.m42 = 0;
17040
+ this.m43 = 0;
17041
+ this.m44 = 1;
17042
+ this.is2D = true;
17043
+ this.isIdentity = true;
17044
+ }
17045
+ static fromMatrix() {
17046
+ return new MockDOMMatrix();
17047
+ }
17048
+ inverse() {
17049
+ return new MockDOMMatrix();
17050
+ }
17051
+ flipX() {
17052
+ return new MockDOMMatrix();
17053
+ }
17054
+ flipY() {
17055
+ return new MockDOMMatrix();
17056
+ }
17057
+ multiply() {
17058
+ return new MockDOMMatrix();
17059
+ }
17060
+ rotate() {
17061
+ return new MockDOMMatrix();
17062
+ }
17063
+ rotateAxisAngle() {
17064
+ return new MockDOMMatrix();
17065
+ }
17066
+ rotateFromVector() {
17067
+ return new MockDOMMatrix();
17068
+ }
17069
+ scale() {
17070
+ return new MockDOMMatrix();
17071
+ }
17072
+ scaleNonUniform() {
17073
+ return new MockDOMMatrix();
17074
+ }
17075
+ skewX() {
17076
+ return new MockDOMMatrix();
17077
+ }
17078
+ skewY() {
17079
+ return new MockDOMMatrix();
17080
+ }
17081
+ toJSON() { }
17082
+ toString() { }
17083
+ transformPoint() {
17084
+ return new MockDOMPoint();
17085
+ }
17086
+ translate() {
17087
+ return new MockDOMMatrix();
17088
+ }
17089
+ }
17090
+ class MockDOMPoint {
17091
+ constructor() {
17092
+ this.w = 1;
17093
+ this.x = 0;
17094
+ this.y = 0;
17095
+ this.z = 0;
17096
+ }
17097
+ toJSON() { }
17098
+ matrixTransform() {
17099
+ return new MockDOMMatrix();
17100
+ }
17101
+ }
17102
+ class MockSVGRect {
17103
+ constructor() {
17104
+ this.height = 10;
17105
+ this.width = 10;
17106
+ this.x = 0;
17107
+ this.y = 0;
17108
+ }
17109
+ }
16784
17110
  class MockStyleElement extends MockHTMLElement {
16785
17111
  constructor(ownerDocument) {
16786
17112
  super(ownerDocument, 'style');
@@ -16813,9 +17139,6 @@ class MockSVGElement extends MockElement {
16813
17139
  get viewportElement() {
16814
17140
  return null;
16815
17141
  }
16816
- focus() {
16817
- /**/
16818
- }
16819
17142
  onunload() {
16820
17143
  /**/
16821
17144
  }
@@ -16833,6 +17156,27 @@ class MockSVGElement extends MockElement {
16833
17156
  return 0;
16834
17157
  }
16835
17158
  }
17159
+ class MockSVGGraphicsElement extends MockSVGElement {
17160
+ getBBox(_options) {
17161
+ return new MockSVGRect();
17162
+ }
17163
+ getCTM() {
17164
+ return new MockDOMMatrix();
17165
+ }
17166
+ getScreenCTM() {
17167
+ return new MockDOMMatrix();
17168
+ }
17169
+ }
17170
+ class MockSVGSVGElement extends MockSVGGraphicsElement {
17171
+ createSVGPoint() {
17172
+ return new MockDOMPoint();
17173
+ }
17174
+ }
17175
+ class MockSVGTextContentElement extends MockSVGGraphicsElement {
17176
+ getComputedTextLength() {
17177
+ return 0;
17178
+ }
17179
+ }
16836
17180
  class MockBaseElement extends MockHTMLElement {
16837
17181
  constructor(ownerDocument) {
16838
17182
  super(ownerDocument, 'base');
@@ -17249,6 +17593,7 @@ const GLOBAL_CONSTRUCTORS = [
17249
17593
  ['CustomEvent', MockCustomEvent],
17250
17594
  ['Event', MockEvent],
17251
17595
  ['Headers', MockHeaders],
17596
+ ['FocusEvent', MockFocusEvent],
17252
17597
  ['KeyboardEvent', MockKeyboardEvent],
17253
17598
  ['MouseEvent', MockMouseEvent],
17254
17599
  ['Request', MockRequest],
@@ -18580,48 +18925,88 @@ const emptyOutputTargets = async (config, compilerCtx, buildCtx) => {
18580
18925
  timeSpan.finish('cleaning dirs finished');
18581
18926
  };
18582
18927
 
18928
+ /**
18929
+ * Parse CSS imports into an object which contains a manifest of imports and a
18930
+ * stylesheet with all imports resolved and concatenated.
18931
+ *
18932
+ * @param config the current config
18933
+ * @param compilerCtx the compiler context (we need filesystem access)
18934
+ * @param buildCtx the build context, we'll need access to diagnostics
18935
+ * @param srcFilePath the source filepath
18936
+ * @param resolvedFilePath the resolved filepath
18937
+ * @param styleText style text we start with
18938
+ * @param styleDocs optional array of style document objects
18939
+ * @returns an object with concatenated styleText and imports
18940
+ */
18583
18941
  const parseCssImports = async (config, compilerCtx, buildCtx, srcFilePath, resolvedFilePath, styleText, styleDocs) => {
18584
18942
  const isCssEntry = resolvedFilePath.toLowerCase().endsWith('.css');
18585
18943
  const allCssImports = [];
18586
- const concatStyleText = await updateCssImports(config, compilerCtx, buildCtx, isCssEntry, srcFilePath, resolvedFilePath, styleText, allCssImports, new Set(), styleDocs);
18944
+ // a Set of previously-resolved file paths that we add to as we traverse the
18945
+ // import tree (to avoid a possible circular dependency and infinite loop)
18946
+ const resolvedFilePaths = new Set();
18947
+ const concatStyleText = await resolveAndFlattenImports(srcFilePath, resolvedFilePath, styleText);
18587
18948
  return {
18588
18949
  imports: allCssImports,
18589
18950
  styleText: concatStyleText,
18590
18951
  };
18591
- };
18592
- const updateCssImports = async (config, compilerCtx, buildCtx, isCssEntry, srcFilePath, resolvedFilePath, styleText, allCssImports, noLoop, styleDocs) => {
18593
- if (noLoop.has(resolvedFilePath)) {
18594
- return styleText;
18595
- }
18596
- noLoop.add(resolvedFilePath);
18597
- if (styleDocs != null) {
18598
- parseStyleDocs(styleDocs, styleText);
18599
- }
18600
- const cssImports = await getCssImports(config, compilerCtx, buildCtx, resolvedFilePath, styleText);
18601
- if (cssImports.length === 0) {
18602
- return styleText;
18603
- }
18604
- for (const cssImport of cssImports) {
18605
- if (!allCssImports.includes(cssImport.filePath)) {
18606
- allCssImports.push(cssImport.filePath);
18952
+ /**
18953
+ * Resolve and flatten all imports for a given CSS file, recursively crawling
18954
+ * the tree of imports to resolve them all and produce a concatenated
18955
+ * stylesheet. We declare this function here, within `parseCssImports`, in order
18956
+ * to get access to `compilerCtx`, `buildCtx`, and more without having to pass
18957
+ * a whole bunch of arguments.
18958
+ *
18959
+ * @param srcFilePath the source filepath
18960
+ * @param resolvedFilePath the resolved filepath
18961
+ * @param styleText style text we start with*
18962
+ * @returns concatenated styles assembled from the various imported stylesheets
18963
+ */
18964
+ async function resolveAndFlattenImports(srcFilePath, resolvedFilePath, styleText) {
18965
+ // if we've seen this path before we early return
18966
+ if (resolvedFilePaths.has(resolvedFilePath)) {
18967
+ return styleText;
18607
18968
  }
18608
- }
18609
- await Promise.all(cssImports.map(async (cssImportData) => {
18610
- await concatCssImport(config, compilerCtx, buildCtx, isCssEntry, srcFilePath, cssImportData, allCssImports, noLoop, styleDocs);
18611
- }));
18612
- return replaceImportDeclarations(styleText, cssImports, isCssEntry);
18613
- };
18614
- const concatCssImport = async (config, compilerCtx, buildCtx, isCssEntry, srcFilePath, cssImportData, allCssImports, noLoop, styleDocs) => {
18615
- cssImportData.styleText = await loadStyleText(compilerCtx, cssImportData);
18616
- if (typeof cssImportData.styleText === 'string') {
18617
- cssImportData.styleText = await updateCssImports(config, compilerCtx, buildCtx, isCssEntry, cssImportData.filePath, cssImportData.filePath, cssImportData.styleText, allCssImports, noLoop, styleDocs);
18618
- }
18619
- else {
18620
- const err = buildError(buildCtx.diagnostics);
18621
- err.messageText = `Unable to read css import: ${cssImportData.srcImport}`;
18622
- err.absFilePath = srcFilePath;
18969
+ resolvedFilePaths.add(resolvedFilePath);
18970
+ if (styleDocs != null) {
18971
+ parseStyleDocs(styleDocs, styleText);
18972
+ }
18973
+ const cssImports = await getCssImports(config, compilerCtx, buildCtx, resolvedFilePath, styleText);
18974
+ if (cssImports.length === 0) {
18975
+ return styleText;
18976
+ }
18977
+ // add any newly-found imports to the 'global' list
18978
+ for (const cssImport of cssImports) {
18979
+ if (!allCssImports.includes(cssImport.filePath)) {
18980
+ allCssImports.push(cssImport.filePath);
18981
+ }
18982
+ }
18983
+ // Recur down the tree of CSS imports, resolving all the imports in
18984
+ // the children of the current file (and, by extension, in their children
18985
+ // and so on)
18986
+ await Promise.all(cssImports.map(async (cssImportData) => {
18987
+ cssImportData.styleText = await loadStyleText(compilerCtx, cssImportData);
18988
+ if (typeof cssImportData.styleText === 'string') {
18989
+ cssImportData.styleText = await resolveAndFlattenImports(cssImportData.filePath, cssImportData.filePath, cssImportData.styleText);
18990
+ }
18991
+ else {
18992
+ // we had some error loading the file from disk, so write a diagnostic
18993
+ const err = buildError(buildCtx.diagnostics);
18994
+ err.messageText = `Unable to read css import: ${cssImportData.srcImport}`;
18995
+ err.absFilePath = srcFilePath;
18996
+ }
18997
+ }));
18998
+ // replace import statements with the actual CSS code in children modules
18999
+ return replaceImportDeclarations(styleText, cssImports, isCssEntry);
18623
19000
  }
18624
19001
  };
19002
+ /**
19003
+ * Load the style text for a CSS file from disk, based on the filepaths set in
19004
+ * our import data.
19005
+ *
19006
+ * @param compilerCtx the compiler context
19007
+ * @param cssImportData the import data for the file we want to read
19008
+ * @returns the contents of the file, if it can be read without error
19009
+ */
18625
19010
  const loadStyleText = async (compilerCtx, cssImportData) => {
18626
19011
  let styleText = null;
18627
19012
  try {
@@ -18637,7 +19022,18 @@ const loadStyleText = async (compilerCtx, cssImportData) => {
18637
19022
  }
18638
19023
  return styleText;
18639
19024
  };
19025
+ /**
19026
+ * Get a manifest of all the CSS imports in a given CSS file
19027
+ *
19028
+ * @param config the current config
19029
+ * @param compilerCtx the compiler context (we need the filesystem)
19030
+ * @param buildCtx the build context, in case we need to set a diagnostic
19031
+ * @param filePath the filepath we're working with
19032
+ * @param styleText the CSS for which we want to retrieve import data
19033
+ * @returns a Promise wrapping a list of CSS import data objects
19034
+ */
18640
19035
  const getCssImports = async (config, compilerCtx, buildCtx, filePath, styleText) => {
19036
+ var _a;
18641
19037
  const imports = [];
18642
19038
  if (!styleText.includes('@import')) {
18643
19039
  // no @import at all, so don't bother
@@ -18645,13 +19041,14 @@ const getCssImports = async (config, compilerCtx, buildCtx, filePath, styleText)
18645
19041
  }
18646
19042
  styleText = stripCssComments(styleText);
18647
19043
  const dir = dirname(filePath);
18648
- const importeeExt = filePath.split('.').pop().toLowerCase();
19044
+ const importeeExt = ((_a = filePath.split('.').pop()) !== null && _a !== void 0 ? _a : '').toLowerCase();
18649
19045
  let r;
18650
19046
  const IMPORT_RE = /(@import)\s+(url\()?\s?(.*?)\s?\)?([^;]*);?/gi;
18651
19047
  while ((r = IMPORT_RE.exec(styleText))) {
18652
19048
  const cssImportData = {
18653
19049
  srcImport: r[0],
18654
19050
  url: r[4].replace(/[\"\'\)]/g, ''),
19051
+ filePath: '',
18655
19052
  };
18656
19053
  if (!isLocalCssImport(cssImportData.srcImport)) {
18657
19054
  // do nothing for @import url(http://external.css)
@@ -18678,7 +19075,10 @@ const getCssImports = async (config, compilerCtx, buildCtx, filePath, styleText)
18678
19075
  cssImportData.altFilePath = normalizePath$1(join(dirPath, fileName));
18679
19076
  }
18680
19077
  }
18681
- if (typeof cssImportData.filePath === 'string') {
19078
+ // we set `filePath` to `""` when the object is created above, so if it
19079
+ // hasn't been changed in the intervening conditionals then we didn't resolve
19080
+ // a filepath for it.
19081
+ if (cssImportData.filePath !== '') {
18682
19082
  imports.push(cssImportData);
18683
19083
  }
18684
19084
  }
@@ -18720,6 +19120,16 @@ const isLocalCssImport = (srcImport) => {
18720
19120
  }
18721
19121
  return true;
18722
19122
  };
19123
+ /**
19124
+ * Replace import declarations (like '@import "foobar";') with the actual CSS
19125
+ * written in the imported module, allowing us to produce a single file from a
19126
+ * tree of stylesheets.
19127
+ *
19128
+ * @param styleText the text within which we want to replace @import statements
19129
+ * @param cssImports information about imported modules
19130
+ * @param isCssEntry whether we're dealing with a CSS file
19131
+ * @returns an updated string with the requisite substitutions
19132
+ */
18723
19133
  const replaceImportDeclarations = (styleText, cssImports, isCssEntry) => {
18724
19134
  for (const cssImport of cssImports) {
18725
19135
  if (isCssEntry) {
@@ -41053,6 +41463,7 @@ const createComponentExport = (cmp) => {
41053
41463
  * using the `dist-custom-elements` output target may have a single 'entry point' for each file containing a component.
41054
41464
  * Each of those files will be independently resolved and loaded by this plugin for further processing by Rollup later
41055
41465
  * in the bundling process.
41466
+ *
41056
41467
  * @param entries the Stencil project files to process. It should be noted that the keys in this object may not
41057
41468
  * necessarily be an absolute or relative path to a file, but may be a Rollup Virtual Module (which begin with \0).
41058
41469
  * @returns the rollup plugin that loads and process a Stencil project's entry points
@@ -41221,9 +41632,9 @@ const fetchUrlSync = (url) => {
41221
41632
  return undefined;
41222
41633
  };
41223
41634
 
41224
- const patchTsSystemFileSystem = (config, stencilSys, inMemoryFs, tsSys) => {
41635
+ const patchTsSystemFileSystem = (config, compilerSys, inMemoryFs, tsSys) => {
41225
41636
  const realpath = (path) => {
41226
- const rp = stencilSys.realpathSync(path);
41637
+ const rp = compilerSys.realpathSync(path);
41227
41638
  if (isString$1(rp)) {
41228
41639
  return rp;
41229
41640
  }
@@ -41231,7 +41642,7 @@ const patchTsSystemFileSystem = (config, stencilSys, inMemoryFs, tsSys) => {
41231
41642
  };
41232
41643
  const getAccessibleFileSystemEntries = (path) => {
41233
41644
  try {
41234
- const entries = stencilSys.readDirSync(path || '.').sort();
41645
+ const entries = compilerSys.readDirSync(path || '.').sort();
41235
41646
  const files = [];
41236
41647
  const directories = [];
41237
41648
  for (const absPath of entries) {
@@ -41256,13 +41667,13 @@ const patchTsSystemFileSystem = (config, stencilSys, inMemoryFs, tsSys) => {
41256
41667
  }
41257
41668
  };
41258
41669
  tsSys.createDirectory = (p) => {
41259
- stencilSys.createDirSync(p, { recursive: true });
41670
+ compilerSys.createDirSync(p, { recursive: true });
41260
41671
  };
41261
41672
  tsSys.directoryExists = (p) => {
41262
41673
  const s = inMemoryFs.statSync(p);
41263
41674
  return s.isDirectory;
41264
41675
  };
41265
- tsSys.exit = stencilSys.exit;
41676
+ tsSys.exit = compilerSys.exit;
41266
41677
  tsSys.fileExists = (p) => {
41267
41678
  let filePath = p;
41268
41679
  if (isRemoteUrl(p)) {
@@ -41271,17 +41682,17 @@ const patchTsSystemFileSystem = (config, stencilSys, inMemoryFs, tsSys) => {
41271
41682
  const s = inMemoryFs.statSync(filePath);
41272
41683
  return !!(s && s.isFile);
41273
41684
  };
41274
- tsSys.getCurrentDirectory = stencilSys.getCurrentDirectory;
41275
- tsSys.getExecutingFilePath = stencilSys.getCompilerExecutingPath;
41685
+ tsSys.getCurrentDirectory = compilerSys.getCurrentDirectory;
41686
+ tsSys.getExecutingFilePath = compilerSys.getCompilerExecutingPath;
41276
41687
  tsSys.getDirectories = (p) => {
41277
- const items = stencilSys.readDirSync(p);
41688
+ const items = compilerSys.readDirSync(p);
41278
41689
  return items.filter((itemPath) => {
41279
41690
  const s = inMemoryFs.statSync(itemPath);
41280
41691
  return !!(s && s.exists && s.isDirectory);
41281
41692
  });
41282
41693
  };
41283
41694
  tsSys.readDirectory = (path, extensions, exclude, include, depth) => {
41284
- const cwd = stencilSys.getCurrentDirectory();
41695
+ const cwd = compilerSys.getCurrentDirectory();
41285
41696
  // TODO(STENCIL-344): Replace `matchFiles` with a function that is publicly exposed
41286
41697
  return t.matchFiles(path, extensions, exclude, include, IS_CASE_SENSITIVE_FILE_NAMES, cwd, depth, getAccessibleFileSystemEntries, realpath);
41287
41698
  };
@@ -41308,9 +41719,9 @@ const patchTsSystemFileSystem = (config, stencilSys, inMemoryFs, tsSys) => {
41308
41719
  tsSys.writeFile = (p, data) => inMemoryFs.writeFile(p, data);
41309
41720
  return tsSys;
41310
41721
  };
41311
- const patchTsSystemWatch = (stencilSys, tsSys) => {
41722
+ const patchTsSystemWatch = (compilerSystem, tsSys) => {
41312
41723
  tsSys.watchDirectory = (p, cb, recursive) => {
41313
- const watcher = stencilSys.watchDirectory(p, (filePath) => {
41724
+ const watcher = compilerSystem.watchDirectory(p, (filePath) => {
41314
41725
  cb(filePath);
41315
41726
  }, recursive);
41316
41727
  return {
@@ -41320,7 +41731,7 @@ const patchTsSystemWatch = (stencilSys, tsSys) => {
41320
41731
  };
41321
41732
  };
41322
41733
  tsSys.watchFile = (p, cb) => {
41323
- const watcher = stencilSys.watchFile(p, (filePath, eventKind) => {
41734
+ const watcher = compilerSystem.watchFile(p, (filePath, eventKind) => {
41324
41735
  if (eventKind === 'fileAdd') {
41325
41736
  cb(filePath, t.FileWatcherEventKind.Created);
41326
41737
  }
@@ -41528,7 +41939,7 @@ const createCustomResolverSync = (sys, inMemoryFs, exts) => {
41528
41939
  * https://github.com/DefinitelyTyped/DefinitelyTyped/blob/d121716ed123957f6a86f8985eb013fcaddab345/types/node/globals.d.ts#L183-L188
41529
41940
  * in mind.
41530
41941
  * @param err the entity to check the type of
41531
- * @return true if the provided value is an instance of `ErrnoException`, `false` otherwise
41942
+ * @returns true if the provided value is an instance of `ErrnoException`, `false` otherwise
41532
41943
  */
41533
41944
  function isErrnoException(err) {
41534
41945
  return err instanceof Error && err.hasOwnProperty('code');
@@ -55573,6 +55984,9 @@ const updateStencilCoreImports = (updatedCoreImportPath) => {
55573
55984
  };
55574
55985
  };
55575
55986
  };
55987
+ /**
55988
+ * A set of imports which we don't want to remove from an output file
55989
+ */
55576
55990
  const KEEP_IMPORTS = new Set([
55577
55991
  'h',
55578
55992
  'setMode',
@@ -55592,37 +56006,75 @@ const KEEP_IMPORTS = new Set([
55592
56006
  'setErrorHandler',
55593
56007
  ]);
55594
56008
 
56009
+ /**
56010
+ * Main output target function for `dist-custom-elements`. This function just
56011
+ * does some organizational work to call the other functions in this module,
56012
+ * which do actual work of generating the rollup configuration, creating an
56013
+ * entry chunk, running, the build, etc.
56014
+ *
56015
+ * @param config the user-supplied compiler configuration we're using
56016
+ * @param compilerCtx the current compiler context
56017
+ * @param buildCtx the current build context
56018
+ * @returns an empty Promise which won't resolve until the work is done!
56019
+ */
55595
56020
  const outputCustomElements = async (config, compilerCtx, buildCtx) => {
56021
+ var _a;
55596
56022
  if (!config.buildDist) {
55597
56023
  return;
55598
56024
  }
55599
- const outputTargets = config.outputTargets.filter(isOutputTargetDistCustomElements);
56025
+ const outputTargets = ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : []).filter(isOutputTargetDistCustomElements);
55600
56026
  if (outputTargets.length === 0) {
55601
56027
  return;
55602
56028
  }
55603
56029
  const bundlingEventMessage = 'generate custom elements';
55604
56030
  const timespan = buildCtx.createTimeSpan(`${bundlingEventMessage} started`);
55605
- await Promise.all(outputTargets.map((o) => bundleCustomElements$1(config, compilerCtx, buildCtx, o)));
56031
+ await Promise.all(outputTargets.map((target) => bundleCustomElements$1(config, compilerCtx, buildCtx, target)));
55606
56032
  timespan.finish(`${bundlingEventMessage} finished`);
55607
56033
  };
56034
+ /**
56035
+ * Get bundle options for our current build and compiler context which we'll use
56036
+ * to generate a Rollup build and so on.
56037
+ *
56038
+ * @param config user-supplied Stencil configuration
56039
+ * @param buildCtx the current build context
56040
+ * @param compilerCtx the current compiler context
56041
+ * @param outputTarget the outputTarget we're currently dealing with
56042
+ * @returns bundle options suitable for generating a rollup configuration
56043
+ */
56044
+ const getBundleOptions = (config, buildCtx, compilerCtx, outputTarget) => ({
56045
+ id: 'customElements',
56046
+ platform: 'client',
56047
+ conditionals: getCustomElementsBuildConditionals(config, buildCtx.components),
56048
+ customTransformers: getCustomElementCustomTransformer(config, compilerCtx, buildCtx.components, outputTarget),
56049
+ externalRuntime: !!outputTarget.externalRuntime,
56050
+ inlineWorkers: true,
56051
+ inputs: {
56052
+ // Here we prefix our index chunk with '\0' to tell Rollup that we're
56053
+ // going to be using virtual modules with this module. A leading '\0'
56054
+ // prevents other plugins from messing with the module. We generate a
56055
+ // string for the index chunk below in the `loader` property.
56056
+ //
56057
+ // @see {@link https://rollupjs.org/guide/en/#conventions} for more info.
56058
+ index: '\0core',
56059
+ },
56060
+ loader: {
56061
+ '\0core': generateEntryPoint$1(outputTarget),
56062
+ },
56063
+ inlineDynamicImports: outputTarget.inlineDynamicImports,
56064
+ preserveEntrySignatures: 'allow-extension',
56065
+ });
56066
+ /**
56067
+ * Get bundle options for rollup, run the rollup build, optionally minify the
56068
+ * output, and write files to disk.
56069
+ * @param config user-supplied Stencil configuration
56070
+ * @param buildCtx the current build context
56071
+ * @param compilerCtx the current compiler context
56072
+ * @param outputTarget the outputTarget we're currently dealing with
56073
+ * @returns an empty promise
56074
+ */
55608
56075
  const bundleCustomElements$1 = async (config, compilerCtx, buildCtx, outputTarget) => {
55609
56076
  try {
55610
- const bundleOpts = {
55611
- id: 'customElements',
55612
- platform: 'client',
55613
- conditionals: getCustomElementsBuildConditionals(config, buildCtx.components),
55614
- customTransformers: getCustomElementCustomTransformer(config, compilerCtx, buildCtx.components, outputTarget),
55615
- externalRuntime: !!outputTarget.externalRuntime,
55616
- inlineWorkers: true,
55617
- inputs: {
55618
- index: '\0core',
55619
- },
55620
- loader: {
55621
- '\0core': generateEntryPoint$1(outputTarget),
55622
- },
55623
- inlineDynamicImports: outputTarget.inlineDynamicImports,
55624
- preserveEntrySignatures: 'allow-extension',
55625
- };
56077
+ const bundleOpts = getBundleOptions(config, buildCtx, compilerCtx, outputTarget);
55626
56078
  addCustomElementInputs(buildCtx, bundleOpts);
55627
56079
  const build = await bundleOutput(config, compilerCtx, buildCtx, bundleOpts);
55628
56080
  if (build) {
@@ -55635,6 +56087,18 @@ const bundleCustomElements$1 = async (config, compilerCtx, buildCtx, outputTarge
55635
56087
  hoistTransitiveImports: false,
55636
56088
  preferConst: true,
55637
56089
  });
56090
+ // the output target should have been validated at this point - as a result, we expect this field
56091
+ // to have been backfilled if it wasn't provided
56092
+ const outputTargetDir = outputTarget.dir;
56093
+ // besides, if it isn't here we do a diagnostic and an early return
56094
+ if (!isString$1(outputTargetDir)) {
56095
+ buildCtx.diagnostics.push({
56096
+ level: 'error',
56097
+ type: 'build',
56098
+ messageText: 'dist-custom-elements output target provided with no output target directory!',
56099
+ });
56100
+ return;
56101
+ }
55638
56102
  const minify = outputTarget.externalRuntime || outputTarget.minify !== true ? false : config.minifyJs;
55639
56103
  const files = rollupOutput.output.map(async (bundle) => {
55640
56104
  if (bundle.type === 'chunk') {
@@ -55649,15 +56113,15 @@ const bundleCustomElements$1 = async (config, compilerCtx, buildCtx, outputTarge
55649
56113
  buildCtx.diagnostics.push(...optimizeResults.diagnostics);
55650
56114
  if (!hasError(optimizeResults.diagnostics) && typeof optimizeResults.output === 'string') {
55651
56115
  code = optimizeResults.output;
55652
- sourceMap = optimizeResults.sourceMap;
55653
56116
  }
55654
- if (sourceMap) {
56117
+ if (optimizeResults.sourceMap) {
56118
+ sourceMap = optimizeResults.sourceMap;
55655
56119
  code = code + getSourceMappingUrlForEndOfFile(bundle.fileName);
55656
- await compilerCtx.fs.writeFile(join(outputTarget.dir, bundle.fileName + '.map'), JSON.stringify(sourceMap), {
56120
+ await compilerCtx.fs.writeFile(join(outputTargetDir, bundle.fileName + '.map'), JSON.stringify(sourceMap), {
55657
56121
  outputTargetType: outputTarget.type,
55658
56122
  });
55659
56123
  }
55660
- await compilerCtx.fs.writeFile(join(outputTarget.dir, bundle.fileName), code, {
56124
+ await compilerCtx.fs.writeFile(join(outputTargetDir, bundle.fileName), code, {
55661
56125
  outputTargetType: outputTarget.type,
55662
56126
  });
55663
56127
  }
@@ -55676,6 +56140,8 @@ const bundleCustomElements$1 = async (config, compilerCtx, buildCtx, outputTarge
55676
56140
  */
55677
56141
  const addCustomElementInputs = (buildCtx, bundleOpts) => {
55678
56142
  const components = buildCtx.components;
56143
+ // an array to store the imports of these modules that we're going to add to our entry chunk
56144
+ const indexImports = [];
55679
56145
  components.forEach((cmp) => {
55680
56146
  const exp = [];
55681
56147
  const exportName = dashToPascalCase$1(cmp.tagName);
@@ -55684,16 +56150,25 @@ const addCustomElementInputs = (buildCtx, bundleOpts) => {
55684
56150
  const coreKey = `\0${exportName}`;
55685
56151
  if (cmp.isPlain) {
55686
56152
  exp.push(`export { ${importName} as ${exportName} } from '${cmp.sourceFilePath}';`);
56153
+ indexImports.push(`export { {${exportName} } from '${coreKey}';`);
55687
56154
  }
55688
56155
  else {
55689
56156
  // the `importName` may collide with the `exportName`, alias it just in case it does with `importAs`
55690
56157
  exp.push(`import { ${importName} as ${importAs}, defineCustomElement as cmpDefCustomEle } from '${cmp.sourceFilePath}';`);
55691
56158
  exp.push(`export const ${exportName} = ${importAs};`);
55692
56159
  exp.push(`export const defineCustomElement = cmpDefCustomEle;`);
56160
+ // Here we push an export (with a rename for `defineCustomElement`) for
56161
+ // this component onto our array which references the `coreKey` (prefixed
56162
+ // with `\0`). We have to do this so that our import is referencing the
56163
+ // correct virtual module, if we instead referenced, for instance,
56164
+ // `cmp.sourceFilePath`, we would end up with duplicated modules in our
56165
+ // output.
56166
+ indexImports.push(`export { ${exportName}, defineCustomElement as defineCustomElement${exportName} } from '${coreKey}';`);
55693
56167
  }
55694
56168
  bundleOpts.inputs[cmp.tagName] = coreKey;
55695
56169
  bundleOpts.loader[coreKey] = exp.join('\n');
55696
56170
  });
56171
+ bundleOpts.loader['\0core'] += indexImports.join('\n');
55697
56172
  };
55698
56173
  /**
55699
56174
  * Generate the entrypoint (`index.ts` file) contents for the `dist-custom-elements` output target
@@ -55711,6 +56186,7 @@ const generateEntryPoint$1 = (outputTarget) => {
55711
56186
  /**
55712
56187
  * Get the series of custom transformers that will be applied to a Stencil project's source code during the TypeScript
55713
56188
  * transpilation process
56189
+ *
55714
56190
  * @param config the configuration for the Stencil project
55715
56191
  * @param compilerCtx the current compiler context
55716
56192
  * @param components the components that will be compiled as a part of the current build
@@ -57502,6 +57978,16 @@ const lazyComponentTransform = (compilerCtx, transformOpts) => {
57502
57978
  };
57503
57979
  };
57504
57980
 
57981
+ /**
57982
+ * Generate rollup output based on a rollup build and a series of options.
57983
+ *
57984
+ * @param build a rollup build
57985
+ * @param options output options for rollup
57986
+ * @param config a user-supplied configuration object
57987
+ * @param entryModules a list of entry modules, for checking which chunks
57988
+ * contain components
57989
+ * @returns a Promise wrapping either build results or `null`
57990
+ */
57505
57991
  const generateRollupOutput = async (build, options, config, entryModules) => {
57506
57992
  if (build == null) {
57507
57993
  return null;
@@ -57509,7 +57995,7 @@ const generateRollupOutput = async (build, options, config, entryModules) => {
57509
57995
  const { output } = await build.generate(options);
57510
57996
  return output.map((chunk) => {
57511
57997
  if (chunk.type === 'chunk') {
57512
- const isCore = Object.keys(chunk.modules).some((m) => m.includes('@stencil/core'));
57998
+ const isCore = Object.keys(chunk.modules).some((m) => m.includes(STENCIL_CORE_ID));
57513
57999
  return {
57514
58000
  type: 'chunk',
57515
58001
  fileName: chunk.fileName,
@@ -58008,7 +58494,8 @@ const getSystemLoader = async (config, compilerCtx, corePath, includePolyfills)
58008
58494
 
58009
58495
  var resourcesUrl = scriptElm ? scriptElm.getAttribute('data-resources-url') || scriptElm.src : '';
58010
58496
  var start = function() {
58011
- var url = new URL('${corePath}', new URL(resourcesUrl, window.location.origin));
58497
+ // if src is not present then origin is "null", and new URL() throws TypeError: Failed to construct 'URL': Invalid base URL
58498
+ var url = new URL('${corePath}', new URL(resourcesUrl, window.location.origin !== 'null' ? window.location.origin : undefined));
58012
58499
  System.import(url.href);
58013
58500
  };
58014
58501
 
@@ -59702,29 +60189,45 @@ const relDts$1 = (fromPath, dtsPath) => {
59702
60189
  * @param config the Stencil configuration associated with the project being compiled
59703
60190
  * @param compilerCtx the current compiler context
59704
60191
  * @param buildCtx the context associated with the current build
59705
- * @param distDtsFilePath the path to a type declaration file (.d.ts) that is being generated for the output target.
59706
- * This path is not necessarily the `components.d.ts` file that is found in the root of a project's `src` directory.
60192
+ * @param typesDir the path to the directory where type declarations are saved
59707
60193
  */
59708
- const generateCustomElementsTypes = async (config, compilerCtx, buildCtx, distDtsFilePath) => {
59709
- const outputTargets = config.outputTargets.filter(isOutputTargetDistCustomElements);
59710
- await Promise.all(outputTargets.map((outputTarget) => generateCustomElementsTypesOutput(config, compilerCtx, buildCtx, distDtsFilePath, outputTarget)));
60194
+ const generateCustomElementsTypes = async (config, compilerCtx, buildCtx, typesDir) => {
60195
+ var _a;
60196
+ const outputTargets = ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : []).filter(isOutputTargetDistCustomElements);
60197
+ await Promise.all(outputTargets.map((outputTarget) => generateCustomElementsTypesOutput(config, compilerCtx, buildCtx, typesDir, outputTarget)));
59711
60198
  };
59712
60199
  /**
59713
60200
  * Generates types for a single `dist-custom-elements` output target definition in a Stencil project's configuration
60201
+ *
59714
60202
  * @param config the Stencil configuration associated with the project being compiled
59715
60203
  * @param compilerCtx the current compiler context
59716
60204
  * @param buildCtx the context associated with the current build
59717
- * @param distDtsFilePath the path to a type declaration file (.d.ts) that is being generated for the output target.
59718
- * This path is not necessarily the `components.d.ts` file that is found in the root of a project's `src` directory.
60205
+ * @param typesDir path to the directory where type declarations are saved
59719
60206
  * @param outputTarget the output target for which types are being currently generated
59720
60207
  */
59721
- const generateCustomElementsTypesOutput = async (config, compilerCtx, buildCtx, distDtsFilePath, outputTarget) => {
60208
+ const generateCustomElementsTypesOutput = async (config, compilerCtx, buildCtx, typesDir, outputTarget) => {
60209
+ // the path where we're going to write the typedef for the whole dist-custom-elements output
59722
60210
  const customElementsDtsPath = join(outputTarget.dir, 'index.d.ts');
59723
- const componentsDtsRelPath = relDts(outputTarget.dir, distDtsFilePath);
60211
+ // the directory where types for the individual components are written
60212
+ const componentsTypeDirectoryRelPath = relative$1(outputTarget.dir, typesDir);
60213
+ const components = buildCtx.components.filter((m) => !m.isCollectionDependency);
59724
60214
  const code = [
59725
60215
  `/* ${config.namespace} custom elements */`,
59726
- ``,
59727
- `import type { Components, JSX } from "${componentsDtsRelPath}";`,
60216
+ ...components.map((component) => {
60217
+ const exportName = dashToPascalCase$1(component.tagName);
60218
+ const importName = component.componentClassName;
60219
+ // typedefs for individual components can be found under paths like
60220
+ // $TYPES_DIR/components/my-component/my-component.d.ts
60221
+ //
60222
+ // To construct this path we:
60223
+ //
60224
+ // - get the relative path to the component's source file from the source directory
60225
+ // - join that relative path to the relative path from the `index.d.ts` file to the
60226
+ // directory where typedefs are saved
60227
+ const componentSourceRelPath = relative$1(config.srcDir, component.sourceFilePath).replace('.tsx', '');
60228
+ const componentDTSPath = join(componentsTypeDirectoryRelPath, componentSourceRelPath);
60229
+ return `export { ${importName} as ${exportName} } from '${componentDTSPath}';`;
60230
+ }),
59728
60231
  ``,
59729
60232
  `/**`,
59730
60233
  ` * Used to manually set the base path where assets can be found.`,
@@ -59744,10 +60247,8 @@ const generateCustomElementsTypesOutput = async (config, compilerCtx, buildCtx,
59744
60247
  ` rel?: (el: EventTarget, eventName: string, listener: EventListenerOrEventListenerObject, options: boolean | AddEventListenerOptions) => void;`,
59745
60248
  `}`,
59746
60249
  `export declare const setPlatformOptions: (opts: SetPlatformOptions) => void;`,
59747
- ``,
59748
- `export type { Components, JSX };`,
59749
- ``,
59750
60250
  ];
60251
+ const componentsDtsRelPath = relDts(outputTarget.dir, join(typesDir, 'components.d.ts'));
59751
60252
  const usersIndexJsPath = join(config.srcDir, 'index.ts');
59752
60253
  const hasUserIndex = await compilerCtx.fs.access(usersIndexJsPath);
59753
60254
  if (hasUserIndex) {
@@ -59760,7 +60261,6 @@ const generateCustomElementsTypesOutput = async (config, compilerCtx, buildCtx,
59760
60261
  await compilerCtx.fs.writeFile(customElementsDtsPath, code.join('\n') + `\n`, {
59761
60262
  outputTargetType: outputTarget.type,
59762
60263
  });
59763
- const components = buildCtx.components.filter((m) => !m.isCollectionDependency);
59764
60264
  await Promise.all(components.map(async (cmp) => {
59765
60265
  const dtsCode = generateCustomElementType(componentsDtsRelPath, cmp);
59766
60266
  const fileName = `${cmp.tagName}.d.ts`;
@@ -59834,20 +60334,21 @@ const generateTypesOutput = async (config, compilerCtx, buildCtx, outputTarget)
59834
60334
  const srcDtsFiles = srcDirItems.filter((srcItem) => srcItem.isFile && isDtsFile$1(srcItem.absPath));
59835
60335
  // Copy .d.ts files from src to dist
59836
60336
  // In addition, all references to @stencil/core are replaced
59837
- let distDtsFilePath;
59838
- await Promise.all(srcDtsFiles.map(async (srcDtsFile) => {
60337
+ const copiedDTSFilePaths = await Promise.all(srcDtsFiles.map(async (srcDtsFile) => {
59839
60338
  const relPath = relative$1(config.srcDir, srcDtsFile.absPath);
59840
60339
  const distPath = join(outputTarget.typesDir, relPath);
59841
60340
  const originalDtsContent = await compilerCtx.fs.readFile(srcDtsFile.absPath);
59842
60341
  const distDtsContent = updateStencilTypesImports(outputTarget.typesDir, distPath, originalDtsContent);
59843
60342
  await compilerCtx.fs.writeFile(distPath, distDtsContent);
59844
- distDtsFilePath = distPath;
60343
+ return distPath;
59845
60344
  }));
60345
+ const distDtsFilePath = copiedDTSFilePaths.slice(-1)[0];
59846
60346
  const distPath = outputTarget.typesDir;
59847
60347
  await generateAppTypes(config, compilerCtx, buildCtx, distPath);
60348
+ const { typesDir } = outputTarget;
59848
60349
  if (distDtsFilePath) {
59849
- await generateCustomElementsTypes(config, compilerCtx, buildCtx, distDtsFilePath);
59850
60350
  await generateCustomElementsBundleTypes(config, compilerCtx, buildCtx, distDtsFilePath);
60351
+ await generateCustomElementsTypes(config, compilerCtx, buildCtx, typesDir);
59851
60352
  }
59852
60353
  };
59853
60354
 
@@ -63642,37 +64143,76 @@ const filesChanged = (buildCtx) => {
63642
64143
  // files changed include updated, added and deleted
63643
64144
  return unique([...buildCtx.filesUpdated, ...buildCtx.filesAdded, ...buildCtx.filesDeleted]).sort();
63644
64145
  };
63645
- const scriptsAdded = (buildCtx) => {
63646
- // collect all the scripts that were added
63647
- return buildCtx.filesAdded
63648
- .filter((f) => {
63649
- return SCRIPT_EXT.some((ext) => f.endsWith(ext.toLowerCase()));
63650
- })
63651
- .map((f) => basename(f));
63652
- };
63653
- const scriptsDeleted = (buildCtx) => {
63654
- // collect all the scripts that were deleted
63655
- return buildCtx.filesDeleted
63656
- .filter((f) => {
63657
- return SCRIPT_EXT.some((ext) => f.endsWith(ext.toLowerCase()));
63658
- })
63659
- .map((f) => basename(f));
63660
- };
63661
- const hasScriptChanges = (buildCtx) => {
63662
- return buildCtx.filesChanged.some((f) => {
63663
- const ext = getExt(f);
63664
- return SCRIPT_EXT.includes(ext);
63665
- });
63666
- };
63667
- const hasStyleChanges = (buildCtx) => {
63668
- return buildCtx.filesChanged.some((f) => {
63669
- const ext = getExt(f);
63670
- return STYLE_EXT.includes(ext);
63671
- });
63672
- };
64146
+ /**
64147
+ * Unary helper function mapping string to string and wrapping `basename`,
64148
+ * which normally takes two string arguments. This means it cannot be passed
64149
+ * to `Array.prototype.map`, but this little helper can!
64150
+ *
64151
+ * @param filePath a filepath to check out
64152
+ * @returns the basename for that filepath
64153
+ */
64154
+ const unaryBasename = (filePath) => basename(filePath);
64155
+ /**
64156
+ * Get the file extension for a path
64157
+ *
64158
+ * @param filePath a path
64159
+ * @returns the file extension (well, characters after the last `'.'`)
64160
+ */
63673
64161
  const getExt = (filePath) => filePath.split('.').pop().toLowerCase();
64162
+ /**
64163
+ * Script extensions which we want to be able to recognize
64164
+ */
63674
64165
  const SCRIPT_EXT = ['ts', 'tsx', 'js', 'jsx'];
64166
+ /**
64167
+ * Helper to check if a filepath has a script extension
64168
+ *
64169
+ * @param filePath a file extension
64170
+ * @returns whether the filepath has a script extension or not
64171
+ */
64172
+ const hasScriptExt = (filePath) => SCRIPT_EXT.includes(getExt(filePath));
63675
64173
  const STYLE_EXT = ['css', 'scss', 'sass', 'pcss', 'styl', 'stylus', 'less'];
64174
+ /**
64175
+ * Helper to check if a filepath has a style extension
64176
+ *
64177
+ * @param filePath a file extension to check
64178
+ * @returns whether the filepath has a style extension or not
64179
+ */
64180
+ const hasStyleExt = (filePath) => STYLE_EXT.includes(getExt(filePath));
64181
+ /**
64182
+ * Get all scripts from a build context that were added
64183
+ *
64184
+ * @param buildCtx the build context
64185
+ * @returns an array of filepaths that were added
64186
+ */
64187
+ const scriptsAdded = (buildCtx) => buildCtx.filesAdded.filter(hasScriptExt).map(unaryBasename);
64188
+ /**
64189
+ * Get all scripts from a build context that were deleted
64190
+ *
64191
+ * @param buildCtx the build context
64192
+ * @returns an array of deleted filepaths
64193
+ */
64194
+ const scriptsDeleted = (buildCtx) => buildCtx.filesDeleted.filter(hasScriptExt).map(unaryBasename);
64195
+ /**
64196
+ * Check whether a build has script changes
64197
+ *
64198
+ * @param buildCtx the build context
64199
+ * @returns whether or not there are script changes
64200
+ */
64201
+ const hasScriptChanges = (buildCtx) => buildCtx.filesChanged.some(hasScriptExt);
64202
+ /**
64203
+ * Check whether a build has style changes
64204
+ *
64205
+ * @param buildCtx the build context
64206
+ * @returns whether or not there are style changes
64207
+ */
64208
+ const hasStyleChanges = (buildCtx) => buildCtx.filesChanged.some(hasStyleExt);
64209
+ /**
64210
+ * Check whether a build has html changes
64211
+ *
64212
+ * @param config the current config
64213
+ * @param buildCtx the build context
64214
+ * @returns whether or not HTML files were changed
64215
+ */
63676
64216
  const hasHtmlChanges = (config, buildCtx) => {
63677
64217
  const anyHtmlChanged = buildCtx.filesChanged.some((f) => f.toLowerCase().endsWith('.html'));
63678
64218
  if (anyHtmlChanged) {
@@ -63886,16 +64426,35 @@ const updateCompilerCtxCache = (config, compilerCtx, path, kind) => {
63886
64426
  }
63887
64427
  };
63888
64428
 
64429
+ /**
64430
+ * All the Boolean options supported by the Stencil CLI
64431
+ */
64432
+ /**
64433
+ * Helper function for initializing a `ConfigFlags` object. Provide any overrides
64434
+ * for default values and off you go!
64435
+ *
64436
+ * @param init an object with any overrides for default values
64437
+ * @returns a complete CLI flag object
64438
+ */
64439
+ const createConfigFlags = (init = {}) => {
64440
+ const flags = {
64441
+ task: null,
64442
+ args: [],
64443
+ knownArgs: [],
64444
+ unknownArgs: [],
64445
+ ...init,
64446
+ };
64447
+ return flags;
64448
+ };
64449
+
63889
64450
  const getConfig = (userConfig) => {
63890
- const config = { ...userConfig };
63891
- if (!config.logger) {
63892
- config.logger = createLogger();
63893
- }
64451
+ var _a, _b;
64452
+ const logger = (_a = userConfig.logger) !== null && _a !== void 0 ? _a : createLogger();
64453
+ const config = { ...userConfig, flags: createConfigFlags((_b = userConfig.flags) !== null && _b !== void 0 ? _b : {}), logger };
63894
64454
  if (!config.sys) {
63895
64455
  config.sys = createSystem({ logger: config.logger });
63896
64456
  }
63897
64457
  setPlatformPath(config.sys.platformPath);
63898
- config.flags = config.flags || {};
63899
64458
  if (config.flags.debug || config.flags.verbose) {
63900
64459
  config.logLevel = 'debug';
63901
64460
  }
@@ -63916,14 +64475,15 @@ const patchFs = (userSys) => {
63916
64475
 
63917
64476
  /**
63918
64477
  * Generate a Stencil compiler instance
63919
- * @param config a Stencil configuration to apply to the compiler instance
64478
+ * @param userConfig a user-provided Stencil configuration to apply to the compiler instance
63920
64479
  * @returns a new instance of a Stencil compiler
64480
+ * @public
63921
64481
  */
63922
- const createCompiler = async (config) => {
64482
+ const createCompiler = async (userConfig) => {
63923
64483
  // actual compiler code
63924
64484
  // could be in a web worker on the browser
63925
64485
  // or the main thread in node
63926
- config = getConfig(config);
64486
+ const config = getConfig(userConfig);
63927
64487
  const diagnostics = [];
63928
64488
  const sys = config.sys;
63929
64489
  const compilerCtx = new CompilerContext();
@@ -64599,7 +65159,7 @@ const getComponentPathContent = (componentGraph, outputTarget) => {
64599
65159
  const dependencies = [
64600
65160
  {
64601
65161
  name: "@stencil/core",
64602
- version: "2.16.1",
65162
+ version: "2.17.2-0",
64603
65163
  main: "compiler/stencil.js",
64604
65164
  resources: [
64605
65165
  "package.json",
@@ -64771,11 +65331,11 @@ const getUserConfigName = (config, correctConfigName) => {
64771
65331
  };
64772
65332
 
64773
65333
  const validateDevServer = (config, diagnostics) => {
64774
- var _a, _b, _c, _d, _e, _f, _g;
65334
+ var _a, _b, _c, _d, _e;
64775
65335
  if ((config.devServer === null || config.devServer) === false) {
64776
65336
  return undefined;
64777
65337
  }
64778
- const flags = (_a = config.flags) !== null && _a !== void 0 ? _a : {};
65338
+ const { flags } = config;
64779
65339
  const devServer = { ...config.devServer };
64780
65340
  if (flags.address && isString$1(flags.address)) {
64781
65341
  devServer.address = flags.address;
@@ -64833,14 +65393,14 @@ const validateDevServer = (config, diagnostics) => {
64833
65393
  if (!isBoolean$1(devServer.websocket)) {
64834
65394
  devServer.websocket = true;
64835
65395
  }
64836
- if ((_b = config === null || config === void 0 ? void 0 : config.flags) === null || _b === void 0 ? void 0 : _b.ssr) {
65396
+ if (flags.ssr) {
64837
65397
  devServer.ssr = true;
64838
65398
  }
64839
65399
  else {
64840
65400
  devServer.ssr = !!devServer.ssr;
64841
65401
  }
64842
65402
  if (devServer.ssr) {
64843
- const wwwOutput = ((_c = config.outputTargets) !== null && _c !== void 0 ? _c : []).find(isOutputTargetWww);
65403
+ const wwwOutput = ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : []).find(isOutputTargetWww);
64844
65404
  devServer.prerenderConfig = wwwOutput === null || wwwOutput === void 0 ? void 0 : wwwOutput.prerenderConfig;
64845
65405
  }
64846
65406
  if (isString$1(config.srcIndexHtml)) {
@@ -64866,15 +65426,15 @@ const validateDevServer = (config, diagnostics) => {
64866
65426
  }
64867
65427
  let serveDir;
64868
65428
  let basePath;
64869
- const wwwOutputTarget = ((_d = config.outputTargets) !== null && _d !== void 0 ? _d : []).find(isOutputTargetWww);
65429
+ const wwwOutputTarget = ((_b = config.outputTargets) !== null && _b !== void 0 ? _b : []).find(isOutputTargetWww);
64870
65430
  if (wwwOutputTarget) {
64871
- const baseUrl = new URL((_e = wwwOutputTarget.baseUrl) !== null && _e !== void 0 ? _e : '', 'http://config.stenciljs.com');
65431
+ const baseUrl = new URL((_c = wwwOutputTarget.baseUrl) !== null && _c !== void 0 ? _c : '', 'http://config.stenciljs.com');
64872
65432
  basePath = baseUrl.pathname;
64873
- serveDir = (_f = wwwOutputTarget.appDir) !== null && _f !== void 0 ? _f : '';
65433
+ serveDir = (_d = wwwOutputTarget.appDir) !== null && _d !== void 0 ? _d : '';
64874
65434
  }
64875
65435
  else {
64876
65436
  basePath = '';
64877
- serveDir = (_g = config.rootDir) !== null && _g !== void 0 ? _g : '';
65437
+ serveDir = (_e = config.rootDir) !== null && _e !== void 0 ? _e : '';
64878
65438
  }
64879
65439
  if (!isString$1(basePath) || basePath.trim() === '') {
64880
65440
  basePath = `/`;
@@ -65008,11 +65568,19 @@ const validateHydrated = (config) => {
65008
65568
  return hydratedFlag;
65009
65569
  };
65010
65570
 
65571
+ /**
65572
+ * Validate and return DIST_COLLECTION output targets, ensuring that the `dir`
65573
+ * property is set on them.
65574
+ *
65575
+ * @param config the user-supplied configuration object
65576
+ * @param userOutputs an array of output targets
65577
+ * @returns an array of validated DIST_COLLECTION output targets
65578
+ */
65011
65579
  const validateCollection = (config, userOutputs) => {
65012
- return userOutputs.filter(isOutputTargetDistCollection).map((o) => {
65580
+ return userOutputs.filter(isOutputTargetDistCollection).map((outputTarget) => {
65013
65581
  return {
65014
- ...o,
65015
- dir: getAbsolutePath(config, o.dir || 'dist/collection'),
65582
+ ...outputTarget,
65583
+ dir: getAbsolutePath(config, outputTarget.dir || 'dist/collection'),
65016
65584
  };
65017
65585
  });
65018
65586
  };
@@ -65346,7 +65914,7 @@ const validateHydrateScript = (config, userOutputs) => {
65346
65914
  // we don't already have a hydrate output target
65347
65915
  // let's still see if we require one because of other output targets
65348
65916
  const hasWwwOutput = userOutputs.filter(isOutputTargetWww).some((o) => isString$1(o.indexHtml));
65349
- const shouldBuildHydrate = (config === null || config === void 0 ? void 0 : config.flags.prerender) || (config === null || config === void 0 ? void 0 : config.flags.ssr);
65917
+ const shouldBuildHydrate = config.flags.prerender || config.flags.ssr;
65350
65918
  if (hasWwwOutput && shouldBuildHydrate) {
65351
65919
  // we're prerendering a www output target, so we'll need a hydrate app
65352
65920
  let hydrateDir;
@@ -65422,7 +65990,7 @@ const validateStats = (userConfig, userOutputs) => {
65422
65990
  };
65423
65991
 
65424
65992
  const validatePrerender = (config, diagnostics, outputTarget) => {
65425
- if (!config.flags || (!config.flags.ssr && !config.flags.prerender && config.flags.task !== 'prerender')) {
65993
+ if (!config.flags.ssr && !config.flags.prerender && config.flags.task !== 'prerender') {
65426
65994
  return;
65427
65995
  }
65428
65996
  outputTarget.baseUrl = normalizePath$1(outputTarget.baseUrl);
@@ -65447,8 +66015,6 @@ const validatePrerender = (config, diagnostics, outputTarget) => {
65447
66015
  }
65448
66016
  };
65449
66017
 
65450
- const HOST_CONFIG_FILENAME = 'host.config.json';
65451
-
65452
66018
  const validateServiceWorker = (config, outputTarget) => {
65453
66019
  if (outputTarget.serviceWorker === false) {
65454
66020
  return;
@@ -65501,14 +66067,15 @@ const validateServiceWorker = (config, outputTarget) => {
65501
66067
  }
65502
66068
  };
65503
66069
  const addGlobIgnores = (config, globIgnores) => {
65504
- globIgnores.push(`**/${HOST_CONFIG_FILENAME}`, `**/*.system.entry.js`, `**/*.system.js`, `**/${config.fsNamespace}.js`, `**/${config.fsNamespace}.esm.js`, `**/${config.fsNamespace}.css`);
66070
+ globIgnores.push(`**/host.config.json`, // the filename of the host configuration
66071
+ `**/*.system.entry.js`, `**/*.system.js`, `**/${config.fsNamespace}.js`, `**/${config.fsNamespace}.esm.js`, `**/${config.fsNamespace}.css`);
65505
66072
  };
65506
66073
  const DEFAULT_GLOB_PATTERNS = ['*.html', '**/*.{js,css,json}'];
65507
66074
  const DEFAULT_FILENAME = 'sw.js';
65508
66075
 
65509
66076
  const validateWww = (config, diagnostics, userOutputs) => {
65510
66077
  const hasOutputTargets = userOutputs.length > 0;
65511
- const hasE2eTests = !!(config.flags && config.flags.e2e);
66078
+ const hasE2eTests = !!config.flags.e2e;
65512
66079
  const userWwwOutputs = userOutputs.filter(isOutputTargetWww);
65513
66080
  if (!hasOutputTargets ||
65514
66081
  (hasE2eTests && !userOutputs.some(isOutputTargetWww) && !userOutputs.some(isOutputTargetDist))) {
@@ -65762,7 +66329,7 @@ const DEFAULT_ROLLUP_CONFIG = {
65762
66329
  const validateTesting = (config, diagnostics) => {
65763
66330
  var _a;
65764
66331
  const testing = (config.testing = Object.assign({}, config.testing || {}));
65765
- if (!config.flags || (!config.flags.e2e && !config.flags.spec)) {
66332
+ if (!config.flags.e2e && !config.flags.spec) {
65766
66333
  return;
65767
66334
  }
65768
66335
  let configPathDir = config.configPath;
@@ -65800,7 +66367,7 @@ const validateTesting = (config, diagnostics) => {
65800
66367
  else {
65801
66368
  testing.rootDir = config.rootDir;
65802
66369
  }
65803
- if (config.flags && typeof config.flags.screenshotConnector === 'string') {
66370
+ if (typeof config.flags.screenshotConnector === 'string') {
65804
66371
  testing.screenshotConnector = config.flags.screenshotConnector;
65805
66372
  }
65806
66373
  if (typeof testing.screenshotConnector === 'string') {
@@ -65922,13 +66489,11 @@ const validateWorkers = (config) => {
65922
66489
  if (typeof config.maxConcurrentWorkers !== 'number') {
65923
66490
  config.maxConcurrentWorkers = 8;
65924
66491
  }
65925
- if (config.flags) {
65926
- if (typeof config.flags.maxWorkers === 'number') {
65927
- config.maxConcurrentWorkers = config.flags.maxWorkers;
65928
- }
65929
- else if (config.flags.ci) {
65930
- config.maxConcurrentWorkers = 4;
65931
- }
66492
+ if (typeof config.flags.maxWorkers === 'number') {
66493
+ config.maxConcurrentWorkers = config.flags.maxWorkers;
66494
+ }
66495
+ else if (config.flags.ci) {
66496
+ config.maxConcurrentWorkers = 4;
65932
66497
  }
65933
66498
  config.maxConcurrentWorkers = Math.max(Math.min(config.maxConcurrentWorkers, 16), 0);
65934
66499
  if (config.devServer) {
@@ -65942,111 +66507,119 @@ const validateWorkers = (config) => {
65942
66507
  * `UnvalidatedConfig` to a `Config`.
65943
66508
  *
65944
66509
  * @param userConfig an unvalidated config that we've gotten from a user
66510
+ * @param bootstrapConfig the initial configuration provided by the user (or generated by Stencil) used to bootstrap
66511
+ * configuration loading and validation
65945
66512
  * @returns an object with config and diagnostics props
65946
66513
  */
65947
- const validateConfig = (userConfig = {}) => {
66514
+ const validateConfig = (userConfig = {}, bootstrapConfig) => {
65948
66515
  const config = Object.assign({}, userConfig || {}); // not positive it's json safe
65949
66516
  const diagnostics = [];
65950
- // copy flags (we know it'll be json safe)
65951
- config.flags = JSON.parse(JSON.stringify(config.flags || {}));
66517
+ const logger = bootstrapConfig.logger || config.logger || createLogger();
66518
+ const validatedConfig = {
66519
+ ...config,
66520
+ // flags _should_ be JSON safe
66521
+ flags: JSON.parse(JSON.stringify(config.flags || {})),
66522
+ logger,
66523
+ };
65952
66524
  // default devMode false
65953
- if (config.flags.prod) {
65954
- config.devMode = false;
65955
- }
65956
- else if (config.flags.dev) {
65957
- config.devMode = true;
65958
- }
65959
- else if (!isBoolean$1(config.devMode)) {
65960
- config.devMode = DEFAULT_DEV_MODE;
65961
- }
65962
- config.extras = config.extras || {};
65963
- config.extras.appendChildSlotFix = !!config.extras.appendChildSlotFix;
65964
- config.extras.cloneNodeFix = !!config.extras.cloneNodeFix;
65965
- config.extras.cssVarsShim = !!config.extras.cssVarsShim;
65966
- config.extras.dynamicImportShim = !!config.extras.dynamicImportShim;
65967
- config.extras.lifecycleDOMEvents = !!config.extras.lifecycleDOMEvents;
65968
- config.extras.safari10 = !!config.extras.safari10;
65969
- config.extras.scriptDataOpts = !!config.extras.scriptDataOpts;
65970
- config.extras.shadowDomShim = !!config.extras.shadowDomShim;
65971
- config.extras.slotChildNodesFix = !!config.extras.slotChildNodesFix;
65972
- config.extras.initializeNextTick = !!config.extras.initializeNextTick;
65973
- config.extras.tagNameTransform = !!config.extras.tagNameTransform;
65974
- config.buildEs5 = config.buildEs5 === true || (!config.devMode && config.buildEs5 === 'prod');
65975
- setBooleanConfig(config, 'minifyCss', null, !config.devMode);
65976
- setBooleanConfig(config, 'minifyJs', null, !config.devMode);
65977
- setBooleanConfig(config, 'sourceMap', null, typeof config.sourceMap === 'undefined' ? false : config.sourceMap);
65978
- setBooleanConfig(config, 'watch', 'watch', false);
65979
- setBooleanConfig(config, 'buildDocs', 'docs', !config.devMode);
65980
- setBooleanConfig(config, 'buildDist', 'esm', !config.devMode || config.buildEs5);
65981
- setBooleanConfig(config, 'profile', 'profile', config.devMode);
65982
- setBooleanConfig(config, 'writeLog', 'log', false);
65983
- setBooleanConfig(config, 'buildAppCore', null, true);
65984
- setBooleanConfig(config, 'autoprefixCss', null, config.buildEs5);
65985
- setBooleanConfig(config, 'validateTypes', null, !config._isTesting);
65986
- setBooleanConfig(config, 'allowInlineScripts', null, true);
65987
- if (!isString$1(config.taskQueue)) {
65988
- config.taskQueue = 'async';
66525
+ if (validatedConfig.flags.prod) {
66526
+ validatedConfig.devMode = false;
66527
+ }
66528
+ else if (validatedConfig.flags.dev) {
66529
+ validatedConfig.devMode = true;
66530
+ }
66531
+ else if (!isBoolean$1(validatedConfig.devMode)) {
66532
+ validatedConfig.devMode = DEFAULT_DEV_MODE;
66533
+ }
66534
+ validatedConfig.extras = validatedConfig.extras || {};
66535
+ validatedConfig.extras.appendChildSlotFix = !!validatedConfig.extras.appendChildSlotFix;
66536
+ validatedConfig.extras.cloneNodeFix = !!validatedConfig.extras.cloneNodeFix;
66537
+ validatedConfig.extras.cssVarsShim = !!validatedConfig.extras.cssVarsShim;
66538
+ validatedConfig.extras.dynamicImportShim = !!validatedConfig.extras.dynamicImportShim;
66539
+ validatedConfig.extras.lifecycleDOMEvents = !!validatedConfig.extras.lifecycleDOMEvents;
66540
+ validatedConfig.extras.safari10 = !!validatedConfig.extras.safari10;
66541
+ validatedConfig.extras.scriptDataOpts = !!validatedConfig.extras.scriptDataOpts;
66542
+ validatedConfig.extras.shadowDomShim = !!validatedConfig.extras.shadowDomShim;
66543
+ validatedConfig.extras.slotChildNodesFix = !!validatedConfig.extras.slotChildNodesFix;
66544
+ validatedConfig.extras.initializeNextTick = !!validatedConfig.extras.initializeNextTick;
66545
+ validatedConfig.extras.tagNameTransform = !!validatedConfig.extras.tagNameTransform;
66546
+ validatedConfig.buildEs5 =
66547
+ validatedConfig.buildEs5 === true || (!validatedConfig.devMode && validatedConfig.buildEs5 === 'prod');
66548
+ setBooleanConfig(validatedConfig, 'minifyCss', null, !validatedConfig.devMode);
66549
+ setBooleanConfig(validatedConfig, 'minifyJs', null, !validatedConfig.devMode);
66550
+ setBooleanConfig(validatedConfig, 'sourceMap', null, typeof validatedConfig.sourceMap === 'undefined' ? false : validatedConfig.sourceMap);
66551
+ setBooleanConfig(validatedConfig, 'watch', 'watch', false);
66552
+ setBooleanConfig(validatedConfig, 'buildDocs', 'docs', !validatedConfig.devMode);
66553
+ setBooleanConfig(validatedConfig, 'buildDist', 'esm', !validatedConfig.devMode || validatedConfig.buildEs5);
66554
+ setBooleanConfig(validatedConfig, 'profile', 'profile', validatedConfig.devMode);
66555
+ setBooleanConfig(validatedConfig, 'writeLog', 'log', false);
66556
+ setBooleanConfig(validatedConfig, 'buildAppCore', null, true);
66557
+ setBooleanConfig(validatedConfig, 'autoprefixCss', null, validatedConfig.buildEs5);
66558
+ setBooleanConfig(validatedConfig, 'validateTypes', null, !validatedConfig._isTesting);
66559
+ setBooleanConfig(validatedConfig, 'allowInlineScripts', null, true);
66560
+ if (!isString$1(validatedConfig.taskQueue)) {
66561
+ validatedConfig.taskQueue = 'async';
65989
66562
  }
65990
66563
  // hash file names
65991
- if (!isBoolean$1(config.hashFileNames)) {
65992
- config.hashFileNames = !config.devMode;
66564
+ if (!isBoolean$1(validatedConfig.hashFileNames)) {
66565
+ validatedConfig.hashFileNames = !validatedConfig.devMode;
65993
66566
  }
65994
- if (!isNumber$1(config.hashedFileNameLength)) {
65995
- config.hashedFileNameLength = DEFAULT_HASHED_FILENAME_LENTH;
66567
+ if (!isNumber$1(validatedConfig.hashedFileNameLength)) {
66568
+ validatedConfig.hashedFileNameLength = DEFAULT_HASHED_FILENAME_LENTH;
65996
66569
  }
65997
- if (config.hashedFileNameLength < MIN_HASHED_FILENAME_LENTH) {
66570
+ if (validatedConfig.hashedFileNameLength < MIN_HASHED_FILENAME_LENTH) {
65998
66571
  const err = buildError(diagnostics);
65999
- err.messageText = `config.hashedFileNameLength must be at least ${MIN_HASHED_FILENAME_LENTH} characters`;
66572
+ err.messageText = `validatedConfig.hashedFileNameLength must be at least ${MIN_HASHED_FILENAME_LENTH} characters`;
66000
66573
  }
66001
- if (config.hashedFileNameLength > MAX_HASHED_FILENAME_LENTH) {
66574
+ if (validatedConfig.hashedFileNameLength > MAX_HASHED_FILENAME_LENTH) {
66002
66575
  const err = buildError(diagnostics);
66003
- err.messageText = `config.hashedFileNameLength cannot be more than ${MAX_HASHED_FILENAME_LENTH} characters`;
66576
+ err.messageText = `validatedConfig.hashedFileNameLength cannot be more than ${MAX_HASHED_FILENAME_LENTH} characters`;
66004
66577
  }
66005
- if (!config.env) {
66006
- config.env = {};
66578
+ if (!validatedConfig.env) {
66579
+ validatedConfig.env = {};
66007
66580
  }
66008
66581
  // get a good namespace
66009
- validateNamespace(config, diagnostics);
66582
+ validateNamespace(validatedConfig, diagnostics);
66010
66583
  // figure out all of the config paths and absolute paths
66011
- validatePaths(config);
66584
+ validatePaths(validatedConfig);
66012
66585
  // outputTargets
66013
- validateOutputTargets(config, diagnostics);
66586
+ validateOutputTargets(validatedConfig, diagnostics);
66014
66587
  // plugins
66015
- validatePlugins(config, diagnostics);
66588
+ validatePlugins(validatedConfig, diagnostics);
66016
66589
  // rollup config
66017
- validateRollupConfig(config);
66590
+ validateRollupConfig(validatedConfig);
66018
66591
  // dev server
66019
- config.devServer = validateDevServer(config, diagnostics);
66592
+ validatedConfig.devServer = validateDevServer(validatedConfig, diagnostics);
66020
66593
  // testing
66021
- validateTesting(config, diagnostics);
66594
+ validateTesting(validatedConfig, diagnostics);
66022
66595
  // hydrate flag
66023
- config.hydratedFlag = validateHydrated(config);
66596
+ validatedConfig.hydratedFlag = validateHydrated(validatedConfig);
66024
66597
  // bundles
66025
- if (Array.isArray(config.bundles)) {
66026
- config.bundles = sortBy(config.bundles, (a) => a.components.length);
66598
+ if (Array.isArray(validatedConfig.bundles)) {
66599
+ validatedConfig.bundles = sortBy(validatedConfig.bundles, (a) => a.components.length);
66027
66600
  }
66028
66601
  else {
66029
- config.bundles = [];
66602
+ validatedConfig.bundles = [];
66030
66603
  }
66031
66604
  // validate how many workers we can use
66032
- validateWorkers(config);
66605
+ validateWorkers(validatedConfig);
66033
66606
  // default devInspector to whatever devMode is
66034
- setBooleanConfig(config, 'devInspector', null, config.devMode);
66035
- if (!config._isTesting) {
66036
- validateDistNamespace(config, diagnostics);
66607
+ setBooleanConfig(validatedConfig, 'devInspector', null, validatedConfig.devMode);
66608
+ if (!validatedConfig._isTesting) {
66609
+ validateDistNamespace(validatedConfig, diagnostics);
66037
66610
  }
66038
- setBooleanConfig(config, 'enableCache', 'cache', true);
66039
- if (!Array.isArray(config.watchIgnoredRegex) && config.watchIgnoredRegex != null) {
66040
- config.watchIgnoredRegex = [config.watchIgnoredRegex];
66611
+ setBooleanConfig(validatedConfig, 'enableCache', 'cache', true);
66612
+ if (!Array.isArray(validatedConfig.watchIgnoredRegex) && validatedConfig.watchIgnoredRegex != null) {
66613
+ validatedConfig.watchIgnoredRegex = [validatedConfig.watchIgnoredRegex];
66041
66614
  }
66042
- config.watchIgnoredRegex = (config.watchIgnoredRegex || []).reduce((arr, reg) => {
66615
+ validatedConfig.watchIgnoredRegex = (validatedConfig.watchIgnoredRegex || []).reduce((arr, reg) => {
66043
66616
  if (reg instanceof RegExp) {
66044
66617
  arr.push(reg);
66045
66618
  }
66046
66619
  return arr;
66047
66620
  }, []);
66048
66621
  return {
66049
- config,
66622
+ config: validatedConfig,
66050
66623
  diagnostics,
66051
66624
  };
66052
66625
  };
@@ -66197,6 +66770,21 @@ const createDefaultTsConfig = (config) => JSON.stringify({
66197
66770
  const hasSrcDirectoryInclude = (includeProp, src) => Array.isArray(includeProp) && includeProp.includes(src);
66198
66771
  const hasStencilConfigInclude = (includeProp) => Array.isArray(includeProp) && includeProp.includes('stencil.config.ts');
66199
66772
 
66773
+ /**
66774
+ * Load and validate a configuration to use throughout the lifetime of any Stencil task (build, test, etc.).
66775
+ *
66776
+ * Users can provide configurations multiple ways simultaneously:
66777
+ * - as an object of the `init` argument to this function
66778
+ * - through a path to a configuration file that exists on disk
66779
+ *
66780
+ * In the case of both being present, the two configurations will be merged. The fields of the former will take precedence
66781
+ * over the fields of the latter.
66782
+ *
66783
+ * @param init the initial configuration provided by the user (or generated by Stencil) used to bootstrap configuration
66784
+ * loading and validation
66785
+ * @returns the results of loading a configuration
66786
+ * @public
66787
+ */
66200
66788
  const loadConfig = async (init = {}) => {
66201
66789
  const results = {
66202
66790
  config: null,
@@ -66210,6 +66798,7 @@ const loadConfig = async (init = {}) => {
66210
66798
  extends: null,
66211
66799
  },
66212
66800
  };
66801
+ const unknownConfig = {};
66213
66802
  try {
66214
66803
  const sys = init.sys || createSystem();
66215
66804
  const config = init.config || {};
@@ -66218,22 +66807,21 @@ const loadConfig = async (init = {}) => {
66218
66807
  if (hasError(results.diagnostics)) {
66219
66808
  return results;
66220
66809
  }
66221
- if (loadedConfigFile != null) {
66810
+ if (loadedConfigFile !== null) {
66222
66811
  // merge the user's config object into their loaded config file
66223
66812
  configPath = loadedConfigFile.configPath;
66224
- results.config = { ...loadedConfigFile, ...config };
66225
- results.config.configPath = configPath;
66226
- results.config.rootDir = normalizePath$1(dirname(configPath));
66813
+ unknownConfig.config = { ...loadedConfigFile, ...config };
66814
+ unknownConfig.config.configPath = configPath;
66815
+ unknownConfig.config.rootDir = normalizePath$1(dirname(configPath));
66227
66816
  }
66228
66817
  else {
66229
66818
  // no stencil.config.ts or .js file, which is fine
66230
- // #0CJS ¯\_(ツ)_/¯
66231
- results.config = { ...config };
66232
- results.config.configPath = null;
66233
- results.config.rootDir = normalizePath$1(sys.getCurrentDirectory());
66819
+ unknownConfig.config = { ...config };
66820
+ unknownConfig.config.configPath = null;
66821
+ unknownConfig.config.rootDir = normalizePath$1(sys.getCurrentDirectory());
66234
66822
  }
66235
- results.config.sys = sys;
66236
- const validated = validateConfig(results.config);
66823
+ unknownConfig.config.sys = sys;
66824
+ const validated = validateConfig(unknownConfig.config, init);
66237
66825
  results.diagnostics.push(...validated.diagnostics);
66238
66826
  if (hasError(results.diagnostics)) {
66239
66827
  return results;
@@ -66248,7 +66836,6 @@ const loadConfig = async (init = {}) => {
66248
66836
  else if (typeof results.config.logLevel !== 'string') {
66249
66837
  results.config.logLevel = 'info';
66250
66838
  }
66251
- results.config.logger = init.logger || results.config.logger || createLogger();
66252
66839
  results.config.logger.setLevel(results.config.logLevel);
66253
66840
  if (!hasError(results.diagnostics)) {
66254
66841
  const tsConfigResults = await validateTsConfig(results.config, sys, init);
@@ -66268,6 +66855,15 @@ const loadConfig = async (init = {}) => {
66268
66855
  }
66269
66856
  return results;
66270
66857
  };
66858
+ /**
66859
+ * Load a Stencil configuration file from disk
66860
+ * @param sys the underlying System entity to use to interact with the operating system
66861
+ * @param diagnostics a series of diagnostics used to track errors & warnings throughout the loading process. Entries
66862
+ * may be added to this list in the event of an error.
66863
+ * @param configPath the path to the configuration file to load
66864
+ * @returns an unvalidated configuration. In the event of an error, additional diagnostics may be pushed to the
66865
+ * provided `diagnostics` argument and `null` will be returned.
66866
+ */
66271
66867
  const loadConfigFile = async (sys, diagnostics, configPath) => {
66272
66868
  let config = null;
66273
66869
  if (isString$1(configPath)) {
@@ -66287,6 +66883,15 @@ const loadConfigFile = async (sys, diagnostics, configPath) => {
66287
66883
  }
66288
66884
  return config;
66289
66885
  };
66886
+ /**
66887
+ * Load the configuration file, based on the environment that Stencil is being run in
66888
+ * @param sys the underlying System entity to use to interact with the operating system
66889
+ * @param diagnostics a series of diagnostics used to track errors & warnings throughout the loading process. Entries
66890
+ * may be added to this list in the event of an error.
66891
+ * @param configFilePath the path to the configuration file to load
66892
+ * @returns an unvalidated configuration. In the event of an error, additional diagnostics may be pushed to the
66893
+ * provided `diagnostics` argument and `null` will be returned.
66894
+ */
66290
66895
  const evaluateConfigFile = async (sys, diagnostics, configFilePath) => {
66291
66896
  let configFileData = null;
66292
66897
  try {
@@ -66311,6 +66916,16 @@ const evaluateConfigFile = async (sys, diagnostics, configFilePath) => {
66311
66916
  }
66312
66917
  return configFileData;
66313
66918
  };
66919
+ /**
66920
+ * Transpiles the provided TypeScript source text into JavaScript.
66921
+ *
66922
+ * This function is intended to be used on a `stencil.config.ts` file
66923
+ *
66924
+ * @param diagnostics a collection of compiler diagnostics to check as a part of the compilation process
66925
+ * @param sourceText the text to transpile
66926
+ * @param filePath the name of the file to transpile
66927
+ * @returns the transpiled text. If there are any diagnostics in the provided collection, the provided source is returned
66928
+ */
66314
66929
  const transpileTypedConfig = (diagnostics, sourceText, filePath) => {
66315
66930
  // let's transpile an awesome stencil.config.ts file into
66316
66931
  // a boring stencil.config.js file