@stencil/core 2.14.2 → 2.15.2

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 (43) hide show
  1. package/bin/stencil +14 -15
  2. package/cli/index.cjs +153 -66
  3. package/cli/index.js +153 -66
  4. package/cli/package.json +1 -1
  5. package/compiler/package.json +1 -1
  6. package/compiler/stencil.js +417 -106
  7. package/compiler/stencil.min.js +2 -2
  8. package/dependencies.json +1 -1
  9. package/dev-server/client/index.js +3 -3
  10. package/dev-server/client/package.json +1 -1
  11. package/dev-server/connector.html +3 -3
  12. package/dev-server/index.js +1 -1
  13. package/dev-server/package.json +1 -1
  14. package/dev-server/server-process.js +2 -2
  15. package/internal/app-data/package.json +1 -1
  16. package/internal/client/css-shim.js +2 -2
  17. package/internal/client/dom.js +1 -1
  18. package/internal/client/index.js +1 -1
  19. package/internal/client/package.json +1 -1
  20. package/internal/client/patch-browser.js +1 -1
  21. package/internal/client/patch-esm.js +1 -1
  22. package/internal/client/polyfills/css-shim.js +1 -1
  23. package/internal/client/shadow-css.js +1 -1
  24. package/internal/hydrate/package.json +1 -1
  25. package/internal/hydrate/runner.d.ts +1 -1
  26. package/internal/hydrate/runner.js +1 -1
  27. package/internal/package.json +1 -1
  28. package/internal/stencil-private.d.ts +39 -3
  29. package/internal/stencil-public-compiler.d.ts +21 -15
  30. package/internal/testing/package.json +1 -1
  31. package/mock-doc/index.cjs +13 -3
  32. package/mock-doc/index.d.ts +4 -0
  33. package/mock-doc/index.js +13 -3
  34. package/mock-doc/package.json +1 -1
  35. package/package.json +5 -5
  36. package/screenshot/package.json +1 -1
  37. package/sys/node/autoprefixer.js +1 -1
  38. package/sys/node/index.js +2046 -1338
  39. package/sys/node/node-fetch.js +1 -1
  40. package/sys/node/package.json +1 -1
  41. package/sys/node/worker.js +1 -1
  42. package/testing/index.js +8 -8
  43. package/testing/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- Stencil Compiler v2.14.2 | MIT Licensed | https://stenciljs.com
2
+ Stencil Compiler v2.15.2 | MIT Licensed | https://stenciljs.com
3
3
  */
4
4
  (function(exports) {
5
5
  'use strict';
@@ -872,7 +872,7 @@ const normalizeDiagnostic = (compilerCtx, diagnostic) => {
872
872
  diagnostic.messageText = diagnostic.messageText.message;
873
873
  }
874
874
  else if (typeof diagnostic.messageText === 'string' && diagnostic.messageText.indexOf('Error: ') === 0) {
875
- diagnostic.messageText = diagnostic.messageText.substr(7);
875
+ diagnostic.messageText = diagnostic.messageText.slice(7);
876
876
  }
877
877
  }
878
878
  if (diagnostic.messageText) {
@@ -1161,7 +1161,7 @@ const loadRollupDiagnostics = (config, compilerCtx, buildCtx, rollupError) => {
1161
1161
  };
1162
1162
  diagnostic.lineNumber = errorLine.lineNumber;
1163
1163
  diagnostic.columnNumber = errorLine.errorCharStart;
1164
- const highlightLine = errorLine.text.substr(loc.column);
1164
+ const highlightLine = errorLine.text.slice(loc.column);
1165
1165
  for (let i = 0; i < highlightLine.length; i++) {
1166
1166
  if (charBreak.has(highlightLine.charAt(i))) {
1167
1167
  break;
@@ -1588,7 +1588,7 @@ const createJsVarName = (fileName) => {
1588
1588
  fileName = fileName.replace(/[|;$%@"<>()+,.{}_\!\/\\]/g, '-');
1589
1589
  fileName = dashToPascalCase$1(fileName);
1590
1590
  if (fileName.length > 1) {
1591
- fileName = fileName[0].toLowerCase() + fileName.substr(1);
1591
+ fileName = fileName[0].toLowerCase() + fileName.slice(1);
1592
1592
  }
1593
1593
  else {
1594
1594
  fileName = fileName.toLowerCase();
@@ -1599,6 +1599,12 @@ const createJsVarName = (fileName) => {
1599
1599
  }
1600
1600
  return fileName;
1601
1601
  };
1602
+ /**
1603
+ * Determines if a given file path points to a type declaration file (ending in .d.ts) or not. This function is
1604
+ * case-insensitive in its heuristics.
1605
+ * @param filePath the path to check
1606
+ * @returns `true` if the given `filePath` points to a type declaration file, `false` otherwise
1607
+ */
1602
1608
  const isDtsFile$1 = (filePath) => {
1603
1609
  const parts = filePath.toLowerCase().split('.');
1604
1610
  if (parts.length > 2) {
@@ -1705,15 +1711,16 @@ const SKIP_DEPS = ['@stencil/core'];
1705
1711
  * @returns an error message if the tag has an invalid name, undefined if the tag name passes all checks
1706
1712
  */
1707
1713
  const validateComponentTag = (tag) => {
1714
+ // we want to check this first since we call some String.prototype methods below
1715
+ if (typeof tag !== 'string') {
1716
+ return `Tag "${tag}" must be a string type`;
1717
+ }
1708
1718
  if (tag !== tag.trim()) {
1709
1719
  return `Tag can not contain white spaces`;
1710
1720
  }
1711
1721
  if (tag !== tag.toLowerCase()) {
1712
1722
  return `Tag can not contain upper case characters`;
1713
1723
  }
1714
- if (typeof tag !== 'string') {
1715
- return `Tag "${tag}" must be a string type`;
1716
- }
1717
1724
  if (tag.length === 0) {
1718
1725
  return `Received empty tag value`;
1719
1726
  }
@@ -3967,16 +3974,16 @@ const createCustomResolverAsync = (sys, inMemoryFs, exts) => {
3967
3974
  };
3968
3975
  };
3969
3976
 
3970
- const buildId = '20220310222720';
3977
+ const buildId = '20220509165949';
3971
3978
  const minfyJsId = 'terser5.6.1_7';
3972
- const optimizeCssId = 'autoprefixer10.2.5_postcss8.2.8_7';
3979
+ const optimizeCssId = 'autoprefixer10.2.5_postcss8.2.13_7';
3973
3980
  const parse5Version = '6.0.1';
3974
3981
  const rollupVersion = '2.42.3';
3975
3982
  const sizzleVersion = '2.42.3';
3976
3983
  const terserVersion = '5.6.1';
3977
3984
  const typescriptVersion = '4.5.4';
3978
- const vermoji = '😃';
3979
- const version$3 = '2.14.2';
3985
+ const vermoji = '🎢';
3986
+ const version$3 = '2.15.2';
3980
3987
  const versions = {
3981
3988
  stencil: version$3,
3982
3989
  parse5: parse5Version,
@@ -4436,7 +4443,7 @@ const createSystem = (c) => {
4436
4443
  const hashArray = Array.from(new Uint8Array(arrayBuffer)); // convert buffer to byte array
4437
4444
  let hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string
4438
4445
  if (typeof hashLength === 'number') {
4439
- hashHex = hashHex.substr(0, hashLength);
4446
+ hashHex = hashHex.slice(0, hashLength);
4440
4447
  }
4441
4448
  return hashHex;
4442
4449
  };
@@ -5061,13 +5068,13 @@ const getCssSelectors = (sel) => {
5061
5068
  if (items[i].length === 0)
5062
5069
  continue;
5063
5070
  if (items[i].charAt(0) === '.') {
5064
- SELECTORS.classNames.push(items[i].substr(1));
5071
+ SELECTORS.classNames.push(items[i].slice(1));
5065
5072
  }
5066
5073
  else if (items[i].charAt(0) === '#') {
5067
- SELECTORS.ids.push(items[i].substr(1));
5074
+ SELECTORS.ids.push(items[i].slice(1));
5068
5075
  }
5069
5076
  else if (items[i].charAt(0) === '[') {
5070
- items[i] = items[i].substr(1).split('=')[0].split(']')[0].trim();
5077
+ items[i] = items[i].slice(1).split('=')[0].split(']')[0].trim();
5071
5078
  SELECTORS.attrs.push(items[i].toLowerCase());
5072
5079
  }
5073
5080
  else if (/[a-z]/g.test(items[i].charAt(0))) {
@@ -8656,7 +8663,7 @@ const loadMinifyJsDiagnostics = (sourceText, diagnostics, error) => {
8656
8663
  };
8657
8664
  d.lineNumber = errorLine.lineNumber;
8658
8665
  d.columnNumber = errorLine.errorCharStart;
8659
- const highlightLine = errorLine.text.substr(d.columnNumber);
8666
+ const highlightLine = errorLine.text.slice(d.columnNumber);
8660
8667
  for (let i = 0; i < highlightLine.length; i++) {
8661
8668
  if (MINIFY_CHAR_BREAK.has(highlightLine.charAt(i))) {
8662
8669
  break;
@@ -9510,7 +9517,7 @@ const standardNormalizeHref = (prerenderConfig, diagnostics, url) => {
9510
9517
  // url should NOT have a trailing slash
9511
9518
  if (href.endsWith('/') && url.pathname !== '/') {
9512
9519
  // this has a trailing slash and it's not the root path
9513
- href = href.substr(0, href.length - 1);
9520
+ href = href.slice(0, -1);
9514
9521
  }
9515
9522
  }
9516
9523
  return href;
@@ -14361,7 +14368,7 @@ function toDataAttribute(str) {
14361
14368
  .toLowerCase());
14362
14369
  }
14363
14370
  function dashToPascalCase(str) {
14364
- str = String(str).substr(5);
14371
+ str = String(str).slice(5);
14365
14372
  return str
14366
14373
  .split('-')
14367
14374
  .map((segment, index) => {
@@ -14565,7 +14572,7 @@ function cssCaseToJsCase(str) {
14565
14572
  .split('-')
14566
14573
  .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
14567
14574
  .join('');
14568
- str = str.substr(0, 1).toLowerCase() + str.substr(1);
14575
+ str = str.slice(0, 1).toLowerCase() + str.slice(1);
14569
14576
  }
14570
14577
  return str;
14571
14578
  }
@@ -16918,6 +16925,17 @@ MockElement.prototype.cloneNode = function (deep) {
16918
16925
  return cloned;
16919
16926
  };
16920
16927
 
16928
+ let sharedDocument;
16929
+ function parseHtmlToDocument(html, ownerDocument = null) {
16930
+ if (ownerDocument == null) {
16931
+ if (sharedDocument == null) {
16932
+ sharedDocument = new MockDocument();
16933
+ }
16934
+ ownerDocument = sharedDocument;
16935
+ }
16936
+ return parseDocumentUtil(ownerDocument, html);
16937
+ }
16938
+
16921
16939
  class MockHeaders {
16922
16940
  constructor(init) {
16923
16941
  this._values = [];
@@ -17125,6 +17143,15 @@ class MockResponse {
17125
17143
  }
17126
17144
  }
17127
17145
 
17146
+ class MockDOMParser {
17147
+ parseFromString(htmlToParse, mimeType) {
17148
+ if (mimeType !== 'text/html') {
17149
+ console.error('XML parsing not implemented yet, continuing as html');
17150
+ }
17151
+ return parseHtmlToDocument(htmlToParse);
17152
+ }
17153
+ }
17154
+
17128
17155
  function addGlobalsToWindowPrototype(mockWinPrototype) {
17129
17156
  GLOBAL_CONSTRUCTORS.forEach(([cstrName, Cstr]) => {
17130
17157
  Object.defineProperty(mockWinPrototype, cstrName, {
@@ -17147,6 +17174,7 @@ const GLOBAL_CONSTRUCTORS = [
17147
17174
  ['MouseEvent', MockMouseEvent],
17148
17175
  ['Request', MockRequest],
17149
17176
  ['Response', MockResponse],
17177
+ ['DOMParser', MockDOMParser],
17150
17178
  ['HTMLAnchorElement', MockAnchorElement],
17151
17179
  ['HTMLBaseElement', MockBaseElement],
17152
17180
  ['HTMLButtonElement', MockButtonElement],
@@ -54294,31 +54322,55 @@ const getTextOfPropertyName = (propName) => {
54294
54322
  }
54295
54323
  return undefined;
54296
54324
  };
54325
+ /**
54326
+ * Generate a series of type references for a given AST node
54327
+ * @param baseNode the AST node to pull type references from
54328
+ * @param sourceFile the source file in which the provided `baseNode` exists
54329
+ * @returns the generated series of type references
54330
+ */
54297
54331
  const getAttributeTypeInfo = (baseNode, sourceFile) => {
54298
54332
  const allReferences = {};
54299
- getAllTypeReferences(baseNode).forEach((rt) => {
54300
- allReferences[rt] = getTypeReferenceLocation(rt, sourceFile);
54333
+ getAllTypeReferences(baseNode).forEach((typeName) => {
54334
+ allReferences[typeName] = getTypeReferenceLocation(typeName, sourceFile);
54301
54335
  });
54302
54336
  return allReferences;
54303
54337
  };
54338
+ /**
54339
+ * Get the text-based name from a TypeScript `EntityName`, which is an identifier of some form
54340
+ * @param entity a TypeScript `EntityName` to retrieve the name of an entity from
54341
+ * @returns the entity's name
54342
+ */
54304
54343
  const getEntityName = (entity) => {
54305
54344
  if (t.isIdentifier(entity)) {
54306
54345
  return entity.escapedText.toString();
54307
54346
  }
54308
54347
  else {
54348
+ // We have qualified name - e.g. const x: Foo.Bar.Baz;
54349
+ // Recurse until we find the 'base' of the qualified name
54309
54350
  return getEntityName(entity.left);
54310
54351
  }
54311
54352
  };
54353
+ /**
54354
+ * Recursively walks the provided AST to collect all TypeScript type references that are found
54355
+ * @param node the node to walk to retrieve type information
54356
+ * @returns the collected type references
54357
+ */
54312
54358
  const getAllTypeReferences = (node) => {
54313
54359
  const referencedTypes = [];
54314
54360
  const visit = (node) => {
54361
+ /**
54362
+ * A type reference node will refer to some type T.
54363
+ * e.g: In `const foo: Bar = {...}` the reference node will contain semantic information about `Bar`.
54364
+ * In TypeScript, types that are also keywords (e.g. `number` in `const foo: number`) are not `TypeReferenceNode`s.
54365
+ */
54315
54366
  if (t.isTypeReferenceNode(node)) {
54316
54367
  referencedTypes.push(getEntityName(node.typeName));
54317
54368
  if (node.typeArguments) {
54369
+ // a type may contain types itself (e.g. generics - Foo<Bar>)
54318
54370
  node.typeArguments
54319
- .filter((ta) => t.isTypeReferenceNode(ta))
54320
- .forEach((tr) => {
54321
- const typeName = tr.typeName;
54371
+ .filter((typeArg) => t.isTypeReferenceNode(typeArg))
54372
+ .forEach((typeRef) => {
54373
+ const typeName = typeRef.typeName;
54322
54374
  if (typeName && typeName.escapedText) {
54323
54375
  referencedTypes.push(typeName.escapedText.toString());
54324
54376
  }
@@ -54339,6 +54391,22 @@ const validateReferences = (diagnostics, references, node) => {
54339
54391
  }
54340
54392
  });
54341
54393
  };
54394
+ /**
54395
+ * Determine where a TypeScript type reference originates from. This is accomplished by interrogating the AST node in
54396
+ * which the type's name appears
54397
+ *
54398
+ * A type may originate:
54399
+ * - from the same file where it is used (a type is declared in some file, `foo.ts`, and later used in the same file)
54400
+ * - from another file (I.E. it is imported and should have an import statement somewhere in the file)
54401
+ * - from a global context
54402
+ * - etc.
54403
+ *
54404
+ * The type may be declared using the `type` or `interface` keywords.
54405
+ *
54406
+ * @param typeName the name of the type to find the origination of
54407
+ * @param tsNode the TypeScript AST node being searched for the provided `typeName`
54408
+ * @returns the context stating where the type originates from
54409
+ */
54342
54410
  const getTypeReferenceLocation = (typeName, tsNode) => {
54343
54411
  const sourceFileObj = tsNode.getSourceFile();
54344
54412
  // Loop through all top level imports to find any reference to the type for 'import' reference location
@@ -58837,8 +58905,18 @@ const serializeCollectionDependencies = (compilerCtx) => {
58837
58905
  return sortBy(collectionDeps, (item) => item.name);
58838
58906
  };
58839
58907
 
58908
+ /**
58909
+ * Update a type declaration file's import declarations using the module `@stencil/core`
58910
+ * @param typesDir the directory where type declaration files are expected to exist
58911
+ * @param dtsFilePath the path of the type declaration file being updated, used to derive the correct import declaration
58912
+ * module
58913
+ * @param dtsContent the content of a type declaration file to update
58914
+ * @returns the updated type declaration file contents
58915
+ */
58840
58916
  const updateStencilTypesImports = (typesDir, dtsFilePath, dtsContent) => {
58841
58917
  const dir = dirname(dtsFilePath);
58918
+ // determine the relative path between the directory of the .d.ts file and the types directory. this value may result
58919
+ // in '.' if they are the same
58842
58920
  const relPath = relative$1(dir, typesDir);
58843
58921
  let coreDtsPath = join(relPath, CORE_FILENAME);
58844
58922
  if (!coreDtsPath.startsWith('.')) {
@@ -58851,6 +58929,74 @@ const updateStencilTypesImports = (typesDir, dtsFilePath, dtsContent) => {
58851
58929
  }
58852
58930
  return dtsContent;
58853
58931
  };
58932
+ /**
58933
+ * Utility for ensuring that naming collisions do not appear in type declaration files for a component's class members
58934
+ * decorated with @Prop, @Event, and @Method
58935
+ * @param typeReferences all type names used by a component class member
58936
+ * @param typeImportData locally/imported/globally used type names, which may be used to prevent naming collisions
58937
+ * @param sourceFilePath the path to the source file of a component using the type being inspected
58938
+ * @param initialType the name of the type that may be updated
58939
+ * @returns the updated type name, which may be the same as the initial type name provided as an argument to this
58940
+ * function
58941
+ */
58942
+ const updateTypeIdentifierNames = (typeReferences, typeImportData, sourceFilePath, initialType) => {
58943
+ let currentTypeName = initialType;
58944
+ // iterate over each of the type references, as there may be >1 reference to inspect
58945
+ for (let typeReference of Object.values(typeReferences)) {
58946
+ const importResolvedFile = getTypeImportPath(typeReference.path, sourceFilePath);
58947
+ if (!typeImportData.hasOwnProperty(importResolvedFile)) {
58948
+ continue;
58949
+ }
58950
+ for (let typesImportDatumElement of typeImportData[importResolvedFile]) {
58951
+ currentTypeName = updateTypeName(currentTypeName, typesImportDatumElement);
58952
+ }
58953
+ }
58954
+ return currentTypeName;
58955
+ };
58956
+ /**
58957
+ * Determine the path of a given type reference, relative to the path of a source file
58958
+ * @param importResolvedFile the path to the file containing the resolve type. may be absolute or relative
58959
+ * @param sourceFilePath the component source file path to resolve against
58960
+ * @returns the path of the type import
58961
+ */
58962
+ const getTypeImportPath = (importResolvedFile, sourceFilePath) => {
58963
+ const isPathRelative = importResolvedFile && importResolvedFile.startsWith('.');
58964
+ if (isPathRelative) {
58965
+ importResolvedFile = resolve$1(dirname(sourceFilePath), importResolvedFile);
58966
+ }
58967
+ return importResolvedFile;
58968
+ };
58969
+ /**
58970
+ * Determine whether the string representation of a type should be replaced with an alias
58971
+ * @param currentTypeName the current string representation of a type
58972
+ * @param typeAlias a type member and a potential different name associated with the type member
58973
+ * @returns the updated string representation of a type. If the type is not updated, the original type name is returned
58974
+ */
58975
+ const updateTypeName = (currentTypeName, typeAlias) => {
58976
+ if (!typeAlias.importName) {
58977
+ return currentTypeName;
58978
+ }
58979
+ // TODO(STENCIL-419): Update this functionality to no longer use a regex
58980
+ // negative lookahead specifying that quotes that designate a string in JavaScript cannot follow some expression
58981
+ const endingStrChar = '(?!("|\'|`))';
58982
+ /**
58983
+ * A regular expression that looks at type names along a [word boundary](https://www.regular-expressions.info/wordboundaries.html).
58984
+ * This is used as the best approximation for replacing type collisions, as this stage of compilation has only
58985
+ * 'flattened' type information in the form of a String.
58986
+ *
58987
+ * This regex should be expected to capture types that are found in generics, unions, intersections, etc., but not
58988
+ * those in string literals. We do not check for a starting quote (" | ' | `) here as some browsers do not support
58989
+ * negative lookbehind. This works "well enough" until STENCIL-419 is completed.
58990
+ */
58991
+ const typeNameRegex = new RegExp(`${typeAlias.localName}\\b${endingStrChar}`, 'g');
58992
+ return currentTypeName.replace(typeNameRegex, typeAlias.importName);
58993
+ };
58994
+ /**
58995
+ * Writes Stencil core typings file to disk for a dist-* output target
58996
+ * @param config the Stencil configuration associated with the project being compiled
58997
+ * @param compilerCtx the current compiler context
58998
+ * @returns the results of writing one or more type declaration files to disk
58999
+ */
58854
59000
  const copyStencilCoreDts = async (config, compilerCtx) => {
58855
59001
  const typesOutputTargets = config.outputTargets.filter(isOutputTargetDistTypes).filter((o) => o.typesDir);
58856
59002
  const srcStencilDtsPath = join(config.sys.getCompilerExecutingPath(), '..', '..', 'internal', CORE_DTS);
@@ -58883,12 +59029,16 @@ const sortImportNames = (a, b) => {
58883
59029
  return 0;
58884
59030
  };
58885
59031
 
58886
- const generateEventTypes = (cmpEvents) => {
58887
- return cmpEvents.map((cmpEvent) => {
59032
+ /**
59033
+ * Generates the individual event types for all @Event() decorated events in a component
59034
+ * @param cmpMeta component runtime metadata for a single component
59035
+ * @param typeImportData locally/imported/globally used type names, which may be used to prevent naming collisions
59036
+ * @returns the generated type metadata
59037
+ */
59038
+ const generateEventTypes = (cmpMeta, typeImportData) => {
59039
+ return cmpMeta.events.map((cmpEvent) => {
58888
59040
  const name = `on${toTitleCase(cmpEvent.name)}`;
58889
- const type = cmpEvent.complexType.original
58890
- ? `(event: CustomEvent<${cmpEvent.complexType.original}>) => void`
58891
- : `CustomEvent`;
59041
+ const type = getEventType$1(cmpEvent, typeImportData, cmpMeta.sourceFilePath);
58892
59042
  return {
58893
59043
  name,
58894
59044
  type,
@@ -58899,23 +59049,59 @@ const generateEventTypes = (cmpEvents) => {
58899
59049
  };
58900
59050
  });
58901
59051
  };
59052
+ /**
59053
+ * Determine the correct type name for all type(s) used by a class member annotated with `@Event()`
59054
+ * @param cmpEvent the compiler metadata for a single `@Event()`
59055
+ * @param typeImportData locally/imported/globally used type names, which may be used to prevent naming collisions
59056
+ * @param componentSourcePath the path to the component on disk
59057
+ * @returns the type associated with a `@Event()`
59058
+ */
59059
+ const getEventType$1 = (cmpEvent, typeImportData, componentSourcePath) => {
59060
+ if (!cmpEvent.complexType.original) {
59061
+ return 'CustomEvent';
59062
+ }
59063
+ const updatedTypeName = updateTypeIdentifierNames(cmpEvent.complexType.references, typeImportData, componentSourcePath, cmpEvent.complexType.original);
59064
+ return `(event: CustomEvent<${updatedTypeName}>) => void`;
59065
+ };
58902
59066
 
58903
- const generateMethodTypes = (cmpMethods) => {
58904
- return cmpMethods.map((cmpMethod) => ({
59067
+ /**
59068
+ * Generates the individual event types for all @Method() decorated events in a component
59069
+ * @param cmpMeta component runtime metadata for a single component
59070
+ * @param typeImportData locally/imported/globally used type names, which may be used to prevent naming collisions
59071
+ * @returns the generated type metadata
59072
+ */
59073
+ const generateMethodTypes = (cmpMeta, typeImportData) => {
59074
+ return cmpMeta.methods.map((cmpMethod) => ({
58905
59075
  name: cmpMethod.name,
58906
- type: cmpMethod.complexType.signature,
59076
+ type: getType$1(cmpMethod, typeImportData, cmpMeta.sourceFilePath),
58907
59077
  optional: false,
58908
59078
  required: false,
58909
59079
  internal: cmpMethod.internal,
58910
59080
  jsdoc: getTextDocs(cmpMethod.docs),
58911
59081
  }));
58912
59082
  };
59083
+ /**
59084
+ * Determine the correct type name for all type(s) used by a class member annotated with `@Method()`
59085
+ * @param cmpMethod the compiler metadata for a single `@Method()`
59086
+ * @param typeImportData locally/imported/globally used type names, which may be used to prevent naming collisions
59087
+ * @param componentSourcePath the path to the component on disk
59088
+ * @returns the type associated with a `@Method()`
59089
+ */
59090
+ function getType$1(cmpMethod, typeImportData, componentSourcePath) {
59091
+ return updateTypeIdentifierNames(cmpMethod.complexType.references, typeImportData, componentSourcePath, cmpMethod.complexType.signature);
59092
+ }
58913
59093
 
58914
- const generatePropTypes = (cmpMeta) => {
59094
+ /**
59095
+ * Generates the individual event types for all @Prop() decorated events in a component
59096
+ * @param cmpMeta component runtime metadata for a single component
59097
+ * @param typeImportData locally/imported/globally used type names, which may be used to prevent naming collisions
59098
+ * @returns the generated type metadata
59099
+ */
59100
+ const generatePropTypes = (cmpMeta, typeImportData) => {
58915
59101
  return [
58916
59102
  ...cmpMeta.properties.map((cmpProp) => ({
58917
59103
  name: cmpProp.name,
58918
- type: cmpProp.complexType.original,
59104
+ type: getType(cmpProp, typeImportData, cmpMeta.sourceFilePath),
58919
59105
  optional: cmpProp.optional,
58920
59106
  required: cmpProp.required,
58921
59107
  internal: cmpProp.internal,
@@ -58931,23 +59117,34 @@ const generatePropTypes = (cmpMeta) => {
58931
59117
  })),
58932
59118
  ];
58933
59119
  };
59120
+ /**
59121
+ * Determine the correct type name for all type(s) used by a class member annotated with `@Prop()`
59122
+ * @param cmpProp the compiler metadata for a single `@Prop()`
59123
+ * @param typeImportData locally/imported/globally used type names, which may be used to prevent naming collisions
59124
+ * @param componentSourcePath the path to the component on disk
59125
+ * @returns the type associated with a `@Prop()`
59126
+ */
59127
+ function getType(cmpProp, typeImportData, componentSourcePath) {
59128
+ return updateTypeIdentifierNames(cmpProp.complexType.references, typeImportData, componentSourcePath, cmpProp.complexType.original);
59129
+ }
58934
59130
 
58935
59131
  /**
58936
- * Generate a string based on the types that are defined within a component.
58937
- *
59132
+ * Generate a string based on the types that are defined within a component
58938
59133
  * @param cmp the metadata for the component that a type definition string is generated for
58939
- * @param importPath the path of the component file
59134
+ * @param typeImportData locally/imported/globally used type names, which may be used to prevent naming collisions
59135
+ * @param areTypesInternal `true` if types being generated are for a project's internal purposes, `false` otherwise
59136
+ * @returns the generated types string alongside additional metadata
58940
59137
  */
58941
- const generateComponentTypes = (cmp, internal) => {
59138
+ const generateComponentTypes = (cmp, typeImportData, areTypesInternal) => {
58942
59139
  const tagName = cmp.tagName.toLowerCase();
58943
59140
  const tagNameAsPascal = dashToPascalCase$1(tagName);
58944
59141
  const htmlElementName = `HTML${tagNameAsPascal}Element`;
58945
- const propAttributes = generatePropTypes(cmp);
58946
- const methodAttributes = generateMethodTypes(cmp.methods);
58947
- const eventAttributes = generateEventTypes(cmp.events);
58948
- const componentAttributes = attributesToMultiLineString([...propAttributes, ...methodAttributes], false, internal);
59142
+ const propAttributes = generatePropTypes(cmp, typeImportData);
59143
+ const methodAttributes = generateMethodTypes(cmp, typeImportData);
59144
+ const eventAttributes = generateEventTypes(cmp, typeImportData);
59145
+ const componentAttributes = attributesToMultiLineString([...propAttributes, ...methodAttributes], false, areTypesInternal);
58949
59146
  const isDep = cmp.isCollectionDependency;
58950
- const jsxAttributes = attributesToMultiLineString([...propAttributes, ...eventAttributes], true, internal);
59147
+ const jsxAttributes = attributesToMultiLineString([...propAttributes, ...eventAttributes], true, areTypesInternal);
58951
59148
  const element = [
58952
59149
  ` interface ${htmlElementName} extends Components.${tagNameAsPascal}, HTMLStencilElement {`,
58953
59150
  ` }`,
@@ -58989,79 +59186,99 @@ const attributesToMultiLineString = (attributes, jsxAttributes, internal) => {
58989
59186
  };
58990
59187
 
58991
59188
  /**
58992
- * Find all referenced types by a component and add them to the importDataObj and return the newly
58993
- * updated importDataObj
58994
- *
58995
- * @param importDataObj key/value of type import file, each value is an array of imported types
58996
- * @param cmpMeta the metadata for the component that is referencing the types
59189
+ * Find all referenced types by a component and add them to the `importDataObj` parameter
59190
+ * @param importDataObj an output parameter that contains the imported types seen thus far by the compiler
59191
+ * @param typeCounts a map of seen types and the number of times the type has been seen
59192
+ * @param cmp the metadata associated with the component whose types are being inspected
58997
59193
  * @param filePath the path of the component file
58998
- * @param config general config that all of stencil uses
59194
+ * @returns the updated import data
58999
59195
  */
59000
- const updateReferenceTypeImports = (importDataObj, allTypes, cmp, filePath) => {
59001
- const updateImportReferences = updateImportReferenceFactory(allTypes, filePath);
59196
+ const updateReferenceTypeImports = (importDataObj, typeCounts, cmp, filePath) => {
59197
+ const updateImportReferences = updateImportReferenceFactory(typeCounts, filePath);
59002
59198
  return [...cmp.properties, ...cmp.events, ...cmp.methods]
59003
59199
  .filter((cmpProp) => cmpProp.complexType && cmpProp.complexType.references)
59004
- .reduce((obj, cmpProp) => {
59005
- return updateImportReferences(obj, cmpProp.complexType.references);
59200
+ .reduce((typesImportData, cmpProp) => {
59201
+ return updateImportReferences(typesImportData, cmpProp.complexType.references);
59006
59202
  }, importDataObj);
59007
59203
  };
59008
- const updateImportReferenceFactory = (allTypes, filePath) => {
59204
+ /**
59205
+ * Factory function to create an `ImportReferenceUpdater` instance
59206
+ * @param typeCounts a key-value store of seen type names and the number of times the type name has been seen
59207
+ * @param filePath the path of the file containing the component whose imports are being inspected
59208
+ * @returns an `ImportReferenceUpdater` instance for updating import references in the provided `filePath`
59209
+ */
59210
+ const updateImportReferenceFactory = (typeCounts, filePath) => {
59211
+ /**
59212
+ * Determines the number of times that a type identifier (name) has been used. If an identifier has been used before,
59213
+ * append the number of times the identifier has been seen to its name to avoid future naming collisions
59214
+ * @param name the identifier name to check for previous usages
59215
+ * @returns the identifier name, potentially with an integer appended to its name if it has been seen before.
59216
+ */
59009
59217
  function getIncrementTypeName(name) {
59010
- const counter = allTypes.get(name);
59218
+ const counter = typeCounts.get(name);
59011
59219
  if (counter === undefined) {
59012
- allTypes.set(name, 1);
59220
+ typeCounts.set(name, 1);
59013
59221
  return name;
59014
59222
  }
59015
- allTypes.set(name, counter + 1);
59223
+ typeCounts.set(name, counter + 1);
59016
59224
  return `${name}${counter}`;
59017
59225
  }
59018
- return (obj, typeReferences) => {
59226
+ return (existingTypeImportData, typeReferences) => {
59019
59227
  Object.keys(typeReferences)
59020
59228
  .map((typeName) => {
59021
59229
  return [typeName, typeReferences[typeName]];
59022
59230
  })
59023
- .forEach(([typeName, type]) => {
59024
- let importFileLocation;
59231
+ .forEach(([typeName, typeReference]) => {
59232
+ let importResolvedFile;
59025
59233
  // If global then there is no import statement needed
59026
- if (type.location === 'global') {
59234
+ if (typeReference.location === 'global') {
59027
59235
  return;
59028
59236
  // If local then import location is the current file
59029
59237
  }
59030
- else if (type.location === 'local') {
59031
- importFileLocation = filePath;
59238
+ else if (typeReference.location === 'local') {
59239
+ importResolvedFile = filePath;
59032
59240
  }
59033
- else if (type.location === 'import') {
59034
- importFileLocation = type.path;
59241
+ else if (typeReference.location === 'import') {
59242
+ importResolvedFile = typeReference.path;
59035
59243
  }
59036
59244
  // If this is a relative path make it absolute
59037
- if (importFileLocation.startsWith('.')) {
59038
- importFileLocation = resolve$1(dirname(filePath), importFileLocation);
59245
+ if (importResolvedFile.startsWith('.')) {
59246
+ importResolvedFile = resolve$1(dirname(filePath), importResolvedFile);
59039
59247
  }
59040
- obj[importFileLocation] = obj[importFileLocation] || [];
59248
+ existingTypeImportData[importResolvedFile] = existingTypeImportData[importResolvedFile] || [];
59041
59249
  // If this file already has a reference to this type move on
59042
- if (obj[importFileLocation].find((df) => df.localName === typeName)) {
59250
+ if (existingTypeImportData[importResolvedFile].find((df) => df.localName === typeName)) {
59043
59251
  return;
59044
59252
  }
59045
59253
  const newTypeName = getIncrementTypeName(typeName);
59046
- obj[importFileLocation].push({
59254
+ existingTypeImportData[importResolvedFile].push({
59047
59255
  localName: typeName,
59048
59256
  importName: newTypeName,
59049
59257
  });
59050
59258
  });
59051
- return obj;
59259
+ return existingTypeImportData;
59052
59260
  };
59053
59261
  };
59054
59262
 
59263
+ /**
59264
+ * Generates and writes a `components.d.ts` file to disk. This file may be written to the `src` directory of a project,
59265
+ * or be written to a directory that is meant to be distributed (e.g. the output directory of `dist-custom-elements`).
59266
+ * @param config the Stencil configuration associated with the project being compiled
59267
+ * @param compilerCtx the current compiler context
59268
+ * @param buildCtx the context associated with the current build
59269
+ * @param destination the relative directory in the filesystem to write the type declaration file to
59270
+ * @returns `true` if the type declaration file written to disk has changed, `false` otherwise
59271
+ */
59055
59272
  const generateAppTypes = async (config, compilerCtx, buildCtx, destination) => {
59056
59273
  // only gather components that are still root ts files we've found and have component metadata
59057
59274
  // the compilerCtx cache may still have files that may have been deleted/renamed
59058
59275
  const timespan = buildCtx.createTimeSpan(`generated app types started`, true);
59059
- const internal = destination === 'src';
59276
+ const areTypesInternal = destination === 'src';
59060
59277
  // Generate d.ts files for component types
59061
- let componentTypesFileContent = generateComponentTypesFile(config, buildCtx, internal);
59278
+ let componentTypesFileContent = generateComponentTypesFile(config, buildCtx, areTypesInternal);
59062
59279
  // immediately write the components.d.ts file to disk and put it into fs memory
59063
59280
  let componentsDtsFilePath = getComponentsDtsSrcFilePath(config);
59064
- if (!internal) {
59281
+ if (!areTypesInternal) {
59065
59282
  componentsDtsFilePath = resolve$1(destination, GENERATED_DTS$1);
59066
59283
  componentTypesFileContent = updateStencilTypesImports(destination, componentsDtsFilePath, componentTypesFileContent);
59067
59284
  }
@@ -59077,21 +59294,30 @@ const generateAppTypes = async (config, compilerCtx, buildCtx, destination) => {
59077
59294
  return hasComponentsDtsChanged;
59078
59295
  };
59079
59296
  /**
59080
- * Generate the component.d.ts file that contains types for all components
59081
- * @param config the project build configuration
59082
- * @param options compiler options from tsconfig
59297
+ * Generates a `component.d.ts` file's contents, which contains the typings for all components in a Stencil project
59298
+ * @param config the Stencil configuration associated with the project being compiled
59299
+ * @param buildCtx the context associated with the current build
59300
+ * @param areTypesInternal determines if non-exported type definitions are being generated or not
59301
+ * @returns the contents of the `components.d.ts` file
59083
59302
  */
59084
- const generateComponentTypesFile = (config, buildCtx, internal) => {
59303
+ const generateComponentTypesFile = (config, buildCtx, areTypesInternal) => {
59085
59304
  let typeImportData = {};
59086
59305
  const c = [];
59087
59306
  const allTypes = new Map();
59088
59307
  const components = buildCtx.components.filter((m) => !m.isCollectionDependency);
59089
59308
  const modules = components.map((cmp) => {
59309
+ /**
59310
+ * Generate a key-value store that uses the path to the file where an import is defined as the key, and an object
59311
+ * containing the import's original name and any 'new' name we give it to avoid collisions. We're generating this
59312
+ * data structure for each Stencil component in series, therefore the memory footprint of this entity will likely
59313
+ * grow as more components (with additional types) are processed.
59314
+ */
59090
59315
  typeImportData = updateReferenceTypeImports(typeImportData, allTypes, cmp, cmp.sourceFilePath);
59091
- return generateComponentTypes(cmp, internal);
59316
+ return generateComponentTypes(cmp, typeImportData, areTypesInternal);
59092
59317
  });
59093
59318
  c.push(COMPONENTS_DTS_HEADER);
59094
59319
  c.push(`import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";`);
59320
+ // write the import statements for our type declaration file
59095
59321
  c.push(...Object.keys(typeImportData).map((filePath) => {
59096
59322
  const typeData = typeImportData[filePath];
59097
59323
  let importFilePath;
@@ -59219,10 +59445,28 @@ const relDts$1 = (fromPath, dtsPath) => {
59219
59445
  return normalizePath$1(dtsPath.replace('.d.ts', ''));
59220
59446
  };
59221
59447
 
59448
+ /**
59449
+ * Entrypoint for generating types for one or more `dist-custom-elements` output targets defined in a Stencil project's
59450
+ * configuration
59451
+ * @param config the Stencil configuration associated with the project being compiled
59452
+ * @param compilerCtx the current compiler context
59453
+ * @param buildCtx the context associated with the current build
59454
+ * @param distDtsFilePath the path to a type declaration file (.d.ts) that is being generated for the output target.
59455
+ * This path is not necessarily the `components.d.ts` file that is found in the root of a project's `src` directory.
59456
+ */
59222
59457
  const generateCustomElementsTypes = async (config, compilerCtx, buildCtx, distDtsFilePath) => {
59223
59458
  const outputTargets = config.outputTargets.filter(isOutputTargetDistCustomElements);
59224
59459
  await Promise.all(outputTargets.map((outputTarget) => generateCustomElementsTypesOutput(config, compilerCtx, buildCtx, distDtsFilePath, outputTarget)));
59225
59460
  };
59461
+ /**
59462
+ * Generates types for a single `dist-custom-elements` output target definition in a Stencil project's configuration
59463
+ * @param config the Stencil configuration associated with the project being compiled
59464
+ * @param compilerCtx the current compiler context
59465
+ * @param buildCtx the context associated with the current build
59466
+ * @param distDtsFilePath the path to a type declaration file (.d.ts) that is being generated for the output target.
59467
+ * This path is not necessarily the `components.d.ts` file that is found in the root of a project's `src` directory.
59468
+ * @param outputTarget the output target for which types are being currently generated
59469
+ */
59226
59470
  const generateCustomElementsTypesOutput = async (config, compilerCtx, buildCtx, distDtsFilePath, outputTarget) => {
59227
59471
  const customElementsDtsPath = join(outputTarget.dir, 'index.d.ts');
59228
59472
  const componentsDtsRelPath = relDts(outputTarget.dir, distDtsFilePath);
@@ -59238,7 +59482,7 @@ const generateCustomElementsTypesOutput = async (config, compilerCtx, buildCtx,
59238
59482
  ` * "setAssetPath(document.currentScript.src)", or using a bundler's replace plugin to`,
59239
59483
  ` * dynamically set the path at build time, such as "setAssetPath(process.env.ASSET_PATH)".`,
59240
59484
  ` * But do note that this configuration depends on how your script is bundled, or lack of`,
59241
- ` * bunding, and where your assets can be loaded from. Additionally custom bundling`,
59485
+ ` * bundling, and where your assets can be loaded from. Additionally custom bundling`,
59242
59486
  ` * will have to ensure the static assets are copied to its build directory.`,
59243
59487
  ` */`,
59244
59488
  `export declare const setAssetPath: (path: string) => void;`,
@@ -59273,6 +59517,13 @@ const generateCustomElementsTypesOutput = async (config, compilerCtx, buildCtx,
59273
59517
  await compilerCtx.fs.writeFile(filePath, dtsCode, { outputTargetType: outputTarget.type });
59274
59518
  }));
59275
59519
  };
59520
+ /**
59521
+ * Generate a type declaration file for a specific Stencil component
59522
+ * @param componentsDtsRelPath the path to a root type declaration file from which commonly used entities can be
59523
+ * referenced from in the newly generated file
59524
+ * @param cmp the component to generate the type declaration file for
59525
+ * @returns the contents of the type declaration file for the provided `cmp`
59526
+ */
59276
59527
  const generateCustomElementType = (componentsDtsRelPath, cmp) => {
59277
59528
  const tagNameAsPascal = dashToPascalCase$1(cmp.tagName);
59278
59529
  const o = [
@@ -59291,6 +59542,13 @@ const generateCustomElementType = (componentsDtsRelPath, cmp) => {
59291
59542
  ];
59292
59543
  return o.join('\n');
59293
59544
  };
59545
+ /**
59546
+ * Determines the relative path between two provided paths. If a type declaration file extension is present on
59547
+ * `dtsPath`, it will be removed from the computed relative path.
59548
+ * @param fromPath the path from which to start at
59549
+ * @param dtsPath the destination path
59550
+ * @returns the relative path from the provided `fromPath` to the `dtsPath`
59551
+ */
59294
59552
  const relDts = (fromPath, dtsPath) => {
59295
59553
  dtsPath = relative$1(fromPath, dtsPath);
59296
59554
  if (!dtsPath.startsWith('.')) {
@@ -59299,13 +59557,28 @@ const relDts = (fromPath, dtsPath) => {
59299
59557
  return normalizePath$1(dtsPath.replace('.d.ts', ''));
59300
59558
  };
59301
59559
 
59560
+ /**
59561
+ * For a single output target, generate types, then copy the Stencil core type declaration file
59562
+ * @param config the Stencil configuration associated with the project being compiled
59563
+ * @param compilerCtx the current compiler context
59564
+ * @param buildCtx the context associated with the current build
59565
+ * @param outputTarget the output target to generate types for
59566
+ */
59302
59567
  const generateTypes = async (config, compilerCtx, buildCtx, outputTarget) => {
59303
59568
  if (!buildCtx.hasError) {
59304
59569
  await generateTypesOutput(config, compilerCtx, buildCtx, outputTarget);
59305
59570
  await copyStencilCoreDts(config, compilerCtx);
59306
59571
  }
59307
59572
  };
59573
+ /**
59574
+ * Generate type definition files and write them to a dist directory
59575
+ * @param config the Stencil configuration associated with the project being compiled
59576
+ * @param compilerCtx the current compiler context
59577
+ * @param buildCtx the context associated with the current build
59578
+ * @param outputTarget the output target to generate types for
59579
+ */
59308
59580
  const generateTypesOutput = async (config, compilerCtx, buildCtx, outputTarget) => {
59581
+ // get all type declaration files in a project's src/ directory
59309
59582
  const srcDirItems = await compilerCtx.fs.readdir(config.srcDir, { recursive: false });
59310
59583
  const srcDtsFiles = srcDirItems.filter((srcItem) => srcItem.isFile && isDtsFile$1(srcItem.absPath));
59311
59584
  // Copy .d.ts files from src to dist
@@ -59327,6 +59600,12 @@ const generateTypesOutput = async (config, compilerCtx, buildCtx, outputTarget)
59327
59600
  }
59328
59601
  };
59329
59602
 
59603
+ /**
59604
+ * Entrypoint for generating types for all output targets
59605
+ * @param config the Stencil configuration associated with the project being compiled
59606
+ * @param compilerCtx the current compiler context
59607
+ * @param buildCtx the context associated with the current build
59608
+ */
59330
59609
  const outputTypes = async (config, compilerCtx, buildCtx) => {
59331
59610
  const outputTargets = config.outputTargets.filter(isOutputTargetDistTypes);
59332
59611
  if (outputTargets.length === 0) {
@@ -61981,7 +62260,7 @@ const validateManifestJsonIcon = async (compilerCtx, buildCtx, manifestFilePath,
61981
62260
  return;
61982
62261
  }
61983
62262
  if (iconSrc.startsWith('/')) {
61984
- iconSrc = iconSrc.substr(1);
62263
+ iconSrc = iconSrc.slice(1);
61985
62264
  }
61986
62265
  const manifestDir = dirname(manifestFilePath);
61987
62266
  const iconPath = join(manifestDir, iconSrc);
@@ -63978,7 +64257,7 @@ const getComponentPathContent = (componentGraph, outputTarget) => {
63978
64257
  const dependencies = [
63979
64258
  {
63980
64259
  name: "@stencil/core",
63981
- version: "2.14.2",
64260
+ version: "2.15.2",
63982
64261
  main: "compiler/stencil.js",
63983
64262
  resources: [
63984
64263
  "package.json",
@@ -64369,11 +64648,20 @@ const validateCopy = (copy, defaultCopy = []) => {
64369
64648
  return unique(copy, (task) => `${task.src}:${task.dest}:${task.keepDirStructure}`);
64370
64649
  };
64371
64650
 
64651
+ /**
64652
+ * Validate one or more `dist-custom-elements` output targets. Validation of an output target may involve back-filling
64653
+ * fields that are omitted with sensible defaults and/or creating additional supporting output targets that were not
64654
+ * explicitly defined by the user
64655
+ * @param config the Stencil configuration associated with the project being compiled
64656
+ * @param userOutputs the output target(s) specified by the user
64657
+ * @returns the validated output target(s)
64658
+ */
64372
64659
  const validateCustomElement = (config, userOutputs) => {
64373
- return userOutputs.filter(isOutputTargetDistCustomElements).reduce((arr, o) => {
64660
+ const defaultDir = 'dist';
64661
+ return userOutputs.filter(isOutputTargetDistCustomElements).reduce((outputs, o) => {
64374
64662
  const outputTarget = {
64375
64663
  ...o,
64376
- dir: getAbsolutePath(config, o.dir || 'dist/components'),
64664
+ dir: getAbsolutePath(config, o.dir || join(defaultDir, 'components')),
64377
64665
  };
64378
64666
  if (!isBoolean$1(outputTarget.empty)) {
64379
64667
  outputTarget.empty = true;
@@ -64381,16 +64669,25 @@ const validateCustomElement = (config, userOutputs) => {
64381
64669
  if (!isBoolean$1(outputTarget.externalRuntime)) {
64382
64670
  outputTarget.externalRuntime = true;
64383
64671
  }
64672
+ // unlike other output targets, Stencil does not allow users to define the output location of types at this time
64673
+ if (outputTarget.generateTypeDeclarations) {
64674
+ const typesDirectory = getAbsolutePath(config, join(defaultDir, 'types'));
64675
+ outputs.push({
64676
+ type: DIST_TYPES,
64677
+ dir: outputTarget.dir,
64678
+ typesDir: typesDirectory,
64679
+ });
64680
+ }
64384
64681
  outputTarget.copy = validateCopy(outputTarget.copy, []);
64385
64682
  if (outputTarget.copy.length > 0) {
64386
- arr.push({
64683
+ outputs.push({
64387
64684
  type: COPY,
64388
64685
  dir: config.rootDir,
64389
64686
  copy: [...outputTarget.copy],
64390
64687
  });
64391
64688
  }
64392
- arr.push(outputTarget);
64393
- return arr;
64689
+ outputs.push(outputTarget);
64690
+ return outputs;
64394
64691
  }, []);
64395
64692
  };
64396
64693
 
@@ -64417,9 +64714,19 @@ const validateCustomOutput = (config, diagnostics, userOutputs) => {
64417
64714
  });
64418
64715
  };
64419
64716
 
64717
+ /**
64718
+ * Validate that the "dist" output targets are valid and ready to go.
64719
+ *
64720
+ * This function will also add in additional output targets to its output, based on the input supplied.
64721
+ *
64722
+ * @param config the compiler config, what else?
64723
+ * @param userOutputs a user-supplied list of output targets.
64724
+ * @returns a list of OutputTargets which have been validated for us.
64725
+ */
64420
64726
  const validateDist = (config, userOutputs) => {
64421
64727
  const distOutputTargets = userOutputs.filter(isOutputTargetDist);
64422
64728
  return distOutputTargets.reduce((outputs, o) => {
64729
+ var _a;
64423
64730
  const distOutputTarget = validateOutputTargetDist(config, o);
64424
64731
  outputs.push(distOutputTarget);
64425
64732
  const namespace = config.fsNamespace || 'app';
@@ -64439,7 +64746,7 @@ const validateDist = (config, userOutputs) => {
64439
64746
  type: COPY,
64440
64747
  dir: lazyDir,
64441
64748
  copyAssets: 'dist',
64442
- copy: [...distOutputTarget.copy],
64749
+ copy: ((_a = distOutputTarget.copy) !== null && _a !== void 0 ? _a : []).concat(),
64443
64750
  });
64444
64751
  outputs.push({
64445
64752
  type: DIST_GLOBAL_STYLES,
@@ -64449,7 +64756,6 @@ const validateDist = (config, userOutputs) => {
64449
64756
  type: DIST_TYPES,
64450
64757
  dir: distOutputTarget.dir,
64451
64758
  typesDir: distOutputTarget.typesDir,
64452
- empty: distOutputTarget.empty,
64453
64759
  });
64454
64760
  if (config.buildDist) {
64455
64761
  if (distOutputTarget.collectionDir) {
@@ -64494,39 +64800,44 @@ const validateDist = (config, userOutputs) => {
64494
64800
  return outputs;
64495
64801
  }, []);
64496
64802
  };
64803
+ /**
64804
+ * Validate that an OutputTargetDist object has what it needs to do it's job.
64805
+ * To enforce this, we have this function return
64806
+ * `Required<d.OutputTargetDist>`, giving us a compile-time check that all
64807
+ * properties are defined (with either user-supplied or default values).
64808
+ *
64809
+ * @param config the current config
64810
+ * @param o the OutputTargetDist object we want to validate
64811
+ * @returns `Required<d.OutputTargetDist>`, i.e. `d.OutputTargetDist` with all
64812
+ * optional properties rendered un-optional.
64813
+ */
64497
64814
  const validateOutputTargetDist = (config, o) => {
64815
+ var _a;
64816
+ // we need to create an object with a bunch of default values here so that
64817
+ // the typescript compiler can infer their types correctly
64498
64818
  const outputTarget = {
64499
64819
  ...o,
64500
64820
  dir: getAbsolutePath(config, o.dir || DEFAULT_DIR),
64821
+ buildDir: isString$1(o.buildDir) ? o.buildDir : DEFAULT_BUILD_DIR,
64822
+ collectionDir: o.collectionDir !== undefined ? o.collectionDir : DEFAULT_COLLECTION_DIR,
64823
+ typesDir: o.typesDir || DEFAULT_TYPES_DIR,
64824
+ esmLoaderPath: o.esmLoaderPath || DEFAULT_ESM_LOADER_DIR,
64825
+ copy: validateCopy((_a = o.copy) !== null && _a !== void 0 ? _a : [], []),
64826
+ polyfills: isBoolean$1(o.polyfills) ? o.polyfills : undefined,
64827
+ empty: isBoolean$1(o.empty) ? o.empty : true,
64501
64828
  };
64502
- if (!isString$1(outputTarget.buildDir)) {
64503
- outputTarget.buildDir = DEFAULT_BUILD_DIR;
64504
- }
64505
64829
  if (!isAbsolute$1(outputTarget.buildDir)) {
64506
64830
  outputTarget.buildDir = join(outputTarget.dir, outputTarget.buildDir);
64507
64831
  }
64508
- if (outputTarget.collectionDir === undefined) {
64509
- outputTarget.collectionDir = DEFAULT_COLLECTION_DIR;
64510
- }
64511
64832
  if (outputTarget.collectionDir && !isAbsolute$1(outputTarget.collectionDir)) {
64512
64833
  outputTarget.collectionDir = join(outputTarget.dir, outputTarget.collectionDir);
64513
64834
  }
64514
- if (!outputTarget.esmLoaderPath) {
64515
- outputTarget.esmLoaderPath = DEFAULT_ESM_LOADER_DIR;
64516
- }
64517
64835
  if (!isAbsolute$1(outputTarget.esmLoaderPath)) {
64518
64836
  outputTarget.esmLoaderPath = resolve$1(outputTarget.dir, outputTarget.esmLoaderPath);
64519
64837
  }
64520
- if (!outputTarget.typesDir) {
64521
- outputTarget.typesDir = DEFAULT_TYPES_DIR;
64522
- }
64523
64838
  if (!isAbsolute$1(outputTarget.typesDir)) {
64524
64839
  outputTarget.typesDir = join(outputTarget.dir, outputTarget.typesDir);
64525
64840
  }
64526
- if (!isBoolean$1(outputTarget.empty)) {
64527
- outputTarget.empty = true;
64528
- }
64529
- outputTarget.copy = validateCopy(outputTarget.copy, []);
64530
64841
  return outputTarget;
64531
64842
  };
64532
64843
  const DEFAULT_DIR = 'dist';
@@ -65175,7 +65486,7 @@ const validateTesting = (config, diagnostics) => {
65175
65486
  * - this regex case shall match file names such as `my-cmp.spec.ts`, `test.spec.ts`
65176
65487
  * - this regex case shall not match file names such as `attest.ts`, `bespec.ts`
65177
65488
  */
65178
- testing.testRegex = '(/__tests__/.*|(\\.|/)(test|spec|e2e))\\.[jt]sx?';
65489
+ testing.testRegex = '(/__tests__/.*|(\\.|/)(test|spec|e2e))\\.[jt]sx?$';
65179
65490
  }
65180
65491
  if (Array.isArray(testing.testMatch)) {
65181
65492
  delete testing.testRegex;