@rindo/core 2.16.1 → 2.17.1

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 (49) hide show
  1. package/cli/config-flags.d.ts +102 -0
  2. package/cli/index.cjs +690 -223
  3. package/cli/index.d.ts +2 -1
  4. package/cli/index.js +690 -223
  5. package/cli/package.json +1 -1
  6. package/compiler/package.json +1 -1
  7. package/compiler/rindo.js +856 -289
  8. package/compiler/rindo.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/rindo-private.d.ts +6 -2
  28. package/internal/rindo-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 +140 -5
  32. package/mock-doc/index.d.ts +76 -1
  33. package/mock-doc/index.js +140 -5
  34. package/mock-doc/package.json +1 -1
  35. package/package.json +5 -3
  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 +124 -69
  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/testing-utils.d.ts +74 -2
  49. package/testing/testing.d.ts +2 -2
package/compiler/rindo.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- Rindo Compiler v2.16.1 | MIT Licensed | https://rindojs.web.app
2
+ Rindo Compiler v2.17.1 | MIT Licensed | https://rindojs.web.app
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 Rindo 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 = ['@rindo/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 getRindoRootUrl = (compilerExe) => new URL('../', compilerExe).href;
2367
- const getRindoModuleUrl = (compilerExe, p) => {
2368
- p = normalizePath$1(p);
2369
- let parts = p.split('/');
2384
+ /**
2385
+ * Get the URL for a Rindo 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 getRindoModuleUrl = (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 getRindoModuleUrl = (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, getRindoRootUrl(compilerExe)).href;
2405
+ const rindoRootUrl = new URL('../', compilerExe).href;
2406
+ return new URL('./' + path, rindoRootUrl).href;
2382
2407
  };
2383
2408
  const getCommonDirUrl = (sys, pkgVersions, dirPath, fileName) => getNodeModuleFetchUrl(sys, pkgVersions, dirPath) + '/' + fileName;
2384
2409
  const getNodeModuleFetchUrl = (sys, pkgVersions, filePath) => {
@@ -4550,7 +4575,7 @@ const createCustomResolverAsync = (sys, inMemoryFs, exts) => {
4550
4575
  };
4551
4576
  };
4552
4577
 
4553
- const buildId = '20220812073157';
4578
+ const buildId = '20230111074933';
4554
4579
  const minfyJsId = 'terser5.6.1_7';
4555
4580
  const optimizeCssId = 'autoprefixer10.2.5_postcss8.4.16_7';
4556
4581
  const parse5Version = '6.0.1';
@@ -4558,8 +4583,8 @@ const rollupVersion = '2.42.3';
4558
4583
  const sizzleVersion = '2.42.3';
4559
4584
  const terserVersion = '5.6.1';
4560
4585
  const typescriptVersion = '4.5.4';
4561
- const vermoji = '🚐';
4562
- const version$3 = '2.16.1';
4586
+ const vermoji = '🍏';
4587
+ const version$3 = '2.17.1';
4563
4588
  const versions = {
4564
4589
  rindo: version$3,
4565
4590
  parse5: parse5Version,
@@ -5108,6 +5133,17 @@ const createSystem = (c) => {
5108
5133
  };
5109
5134
 
5110
5135
  let cssProcessor;
5136
+ /**
5137
+ * Autoprefix a CSS string, adding vendor prefixes to make sure that what
5138
+ * is written in the CSS will render correctly in our range of supported browsers.
5139
+ * This function uses PostCSS in compbination with the Autoprefix plugin to
5140
+ * automatically add vendor prefixes based on a list of browsers which we want
5141
+ * to support.
5142
+ *
5143
+ * @param cssText the text to be prefixed
5144
+ * @param opts an optional param with options for Autoprefixer
5145
+ * @returns a Promise wrapping some prefixed CSS as well as diagnostics
5146
+ */
5111
5147
  const autoprefixCss = async (cssText, opts) => {
5112
5148
  const output = {
5113
5149
  output: cssText,
@@ -5117,7 +5153,7 @@ const autoprefixCss = async (cssText, opts) => {
5117
5153
  return output;
5118
5154
  }
5119
5155
  try {
5120
- const autoprefixerOpts = opts != null && typeof opts === 'object' ? opts : DEFAULT_AUTOPREFIX_LEGACY;
5156
+ const autoprefixerOpts = opts != null && typeof opts === 'object' ? opts : DEFAULT_AUTOPREFIX_OPTIONS;
5121
5157
  const processor = getProcessor(autoprefixerOpts);
5122
5158
  const result = await processor.process(cssText, { map: null });
5123
5159
  result.warnings().forEach((warning) => {
@@ -5173,6 +5209,12 @@ const autoprefixCss = async (cssText, opts) => {
5173
5209
  }
5174
5210
  return output;
5175
5211
  };
5212
+ /**
5213
+ * Get the processor for PostCSS and the Autoprefixer plugin
5214
+ *
5215
+ * @param autoprefixerOpts Options for Autoprefixer
5216
+ * @returns postCSS with the Autoprefixer plugin applied
5217
+ */
5176
5218
  const getProcessor = (autoprefixerOpts) => {
5177
5219
  const { postcss, autoprefixer } = requireFunc('../sys/node/autoprefixer.js');
5178
5220
  if (!cssProcessor) {
@@ -5180,7 +5222,19 @@ const getProcessor = (autoprefixerOpts) => {
5180
5222
  }
5181
5223
  return cssProcessor;
5182
5224
  };
5183
- const DEFAULT_AUTOPREFIX_LEGACY = {
5225
+ /**
5226
+ * Default options for the Autoprefixer PostCSS plugin. See the documentation:
5227
+ * https://github.com/postcss/autoprefixer#options for a complete list.
5228
+ *
5229
+ * This default option set will:
5230
+ *
5231
+ * - override the default browser list (`overrideBrowserslist`)
5232
+ * - turn off the visual cascade (`cascade`)
5233
+ * - disable auto-removing outdated prefixes (`remove`)
5234
+ * - set `flexbox` to `"no-2009"`, which limits prefixing for flexbox to the
5235
+ * final and IE 10 versions of the specification
5236
+ */
5237
+ const DEFAULT_AUTOPREFIX_OPTIONS = {
5184
5238
  overrideBrowserslist: ['last 2 versions', 'iOS >= 9', 'Android >= 4.4', 'Explorer >= 11', 'ExplorerMobile >= 11'],
5185
5239
  cascade: false,
5186
5240
  remove: false,
@@ -5976,6 +6030,13 @@ const resolveStylesheetUrl = async (nodes, resolveUrl, resolved) => {
5976
6030
  }
5977
6031
  };
5978
6032
 
6033
+ /**
6034
+ * Optimize a CSS file, optionally running an autoprefixer and a minifier
6035
+ * depending on the options set on the input options argument.
6036
+ *
6037
+ * @param inputOpts input CSS options
6038
+ * @returns a promise wrapping the optimized output
6039
+ */
5979
6040
  const optimizeCss$1 = async (inputOpts) => {
5980
6041
  let result = {
5981
6042
  output: inputOpts.input,
@@ -11504,6 +11565,16 @@ MagicString$2.prototype.trimStart = function trimStart (charType) {
11504
11565
  return this;
11505
11566
  };
11506
11567
 
11568
+ /**
11569
+ * Parse CSS docstrings that Rindo supports, as documented here:
11570
+ * https://rindojs.web.app/docs/docs-json#css-variables
11571
+ *
11572
+ * Docstrings found in the supplied style text will be added to the
11573
+ * `styleDocs` param
11574
+ *
11575
+ * @param styleDocs the array to hold formatted CSS docstrings
11576
+ * @param styleText the CSS text we're working with
11577
+ */
11507
11578
  function parseStyleDocs(styleDocs, styleText) {
11508
11579
  if (typeof styleText !== 'string') {
11509
11580
  return;
@@ -11520,10 +11591,18 @@ function parseStyleDocs(styleDocs, styleText) {
11520
11591
  styleText = styleText.substring(endIndex + CSS_DOC_END.length);
11521
11592
  }
11522
11593
  }
11594
+ /**
11595
+ * Parse a CSS comment string and insert it into the provided array of
11596
+ * style docstrings.
11597
+ *
11598
+ * @param styleDocs an array which will be modified with the docstring
11599
+ * @param comment the comment string
11600
+ */
11523
11601
  function parseCssComment(styleDocs, comment) {
11524
11602
  /**
11525
11603
  * @prop --max-width: Max width of the alert
11526
11604
  */
11605
+ // (the above is an example of what these comments might look like)
11527
11606
  const lines = comment.split(/\r?\n/).map((line) => {
11528
11607
  line = line.trim();
11529
11608
  while (line.startsWith('*')) {
@@ -11551,11 +11630,19 @@ function parseCssComment(styleDocs, comment) {
11551
11630
  styleDocs.push(cssDoc);
11552
11631
  }
11553
11632
  });
11554
- return styleDocs;
11555
11633
  }
11556
- const CSS_DOC_START = `/**`;
11557
- const CSS_DOC_END = `*/`;
11558
- const CSS_PROP_ANNOTATION = `@prop`;
11634
+ /**
11635
+ * Opening syntax for a CSS docstring
11636
+ */
11637
+ const CSS_DOC_START = '/**';
11638
+ /**
11639
+ * Closing syntax for a CSS docstring
11640
+ */
11641
+ const CSS_DOC_END = '*/';
11642
+ /**
11643
+ * The `@prop` annotation we support within CSS docstrings
11644
+ */
11645
+ const CSS_PROP_ANNOTATION = '@prop';
11559
11646
 
11560
11647
  /**
11561
11648
  * @license
@@ -12008,6 +12095,12 @@ const parseImportPath = (importPath) => {
12008
12095
  return parsedPath;
12009
12096
  };
12010
12097
 
12098
+ /**
12099
+ * Strip out comments from some CSS
12100
+ *
12101
+ * @param input the string we'd like to de-comment
12102
+ * @returns de-commented CSS!
12103
+ */
12011
12104
  const stripCssComments = (input) => {
12012
12105
  let isInsideString = null;
12013
12106
  let currentCharacter = '';
@@ -12044,6 +12137,53 @@ const stripCssComments = (input) => {
12044
12137
  return returnValue;
12045
12138
  };
12046
12139
 
12140
+ /**
12141
+ * A regular expression for matching CSS import statements
12142
+ *
12143
+ * According to https://developer.mozilla.org/en-US/docs/Web/CSS/@import
12144
+ * the formal grammar for CSS import statements is:
12145
+ *
12146
+ * ```
12147
+ * @import [ <url> | <string> ]
12148
+ * [ supports( [ <supports-condition> | <declaration> ] ) ]?
12149
+ * <media-query-list>? ;
12150
+ * ```
12151
+ *
12152
+ * Thus the string literal `"@import"` will be followed by a `<url>` or a
12153
+ * `<string>`, where a `<url>` may be a relative or absolute URL _or_ a `url()`
12154
+ * function.
12155
+ *
12156
+ * Thus the regular expression needs to match:
12157
+ *
12158
+ * - the string `"@import
12159
+ * - any amount of whitespace
12160
+ * - a URL, comprised of:
12161
+ * - an optional `url(` function opener
12162
+ * - a non-greedy match on any characters (to match the argument to the URL
12163
+ * function)
12164
+ * - an optional `)` closing paren on the `url()` function
12165
+ * - trailing characters after the URL, given by anything which doesn't match
12166
+ * the line-terminator `;`
12167
+ * - this can match media queries, support conditions, and so on
12168
+ * - a line-terminating semicolon
12169
+ *
12170
+ * The regex has 4 capture groups:
12171
+ *
12172
+ * 1. `@import`
12173
+ * 2. `url(`
12174
+ * 3. characters after `url(`
12175
+ * 4. all characters other than `;`, greedily matching
12176
+ *
12177
+ * We typically only care about group 4 here.
12178
+ */
12179
+ const CSS_IMPORT_RE = /(@import)\s+(url\()?\s?(.*?)\s?\)?([^;]*);?/gi;
12180
+ /**
12181
+ * Our main entry point to this module. This performs an async transformation
12182
+ * of CSS input to ESM.
12183
+ *
12184
+ * @param input CSS input to be transformed to ESM
12185
+ * @returns a promise wrapping transformed ESM output
12186
+ */
12047
12187
  const transformCssToEsm = async (input) => {
12048
12188
  const results = transformCssToEsmModule(input);
12049
12189
  const optimizeResults = await optimizeCss$1({
@@ -12060,10 +12200,22 @@ const transformCssToEsm = async (input) => {
12060
12200
  results.styleText = optimizeResults.output;
12061
12201
  return generateTransformCssToEsm(input, results);
12062
12202
  };
12203
+ /**
12204
+ * A sync function for transforming input CSS to ESM
12205
+ *
12206
+ * @param input the input CSS we're going to transform
12207
+ * @returns transformed ESM output
12208
+ */
12063
12209
  const transformCssToEsmSync = (input) => {
12064
12210
  const results = transformCssToEsmModule(input);
12065
12211
  return generateTransformCssToEsm(input, results);
12066
12212
  };
12213
+ /**
12214
+ * Performs the actual transformation from CSS to ESM
12215
+ *
12216
+ * @param input input CSS to be transformed
12217
+ * @returns ESM output
12218
+ */
12067
12219
  const transformCssToEsmModule = (input) => {
12068
12220
  const results = {
12069
12221
  styleText: input.input,
@@ -12108,6 +12260,14 @@ const transformCssToEsmModule = (input) => {
12108
12260
  }
12109
12261
  return results;
12110
12262
  };
12263
+ /**
12264
+ * Updated the `output` property on `results` with appropriate import statements for
12265
+ * the CSS import tree and the module type.
12266
+ *
12267
+ * @param input the CSS to ESM transform input
12268
+ * @param results the corresponding output
12269
+ * @returns the modified ESM output
12270
+ */
12111
12271
  const generateTransformCssToEsm = (input, results) => {
12112
12272
  const s = new MagicString$2('');
12113
12273
  if (input.module === 'cjs') {
@@ -12137,6 +12297,15 @@ const generateTransformCssToEsm = (input, results) => {
12137
12297
  results.output = s.toString();
12138
12298
  return results;
12139
12299
  };
12300
+ /**
12301
+ * Get all of the CSS imports in a file
12302
+ *
12303
+ * @param varNames a set into which new names will be added
12304
+ * @param cssText the CSS text in question
12305
+ * @param filePath the file path to the file in question
12306
+ * @param modeName the current mode name
12307
+ * @returns an array of import objects
12308
+ */
12140
12309
  const getCssToEsmImports = (varNames, cssText, filePath, modeName) => {
12141
12310
  const cssImports = [];
12142
12311
  if (!cssText.includes('@import')) {
@@ -12178,10 +12347,22 @@ const getCssToEsmImports = (varNames, cssText, filePath, modeName) => {
12178
12347
  }
12179
12348
  return cssImports;
12180
12349
  };
12181
- const CSS_IMPORT_RE = /(@import)\s+(url\()?\s?(.*?)\s?\)?([^;]*);?/gi;
12350
+ /**
12351
+ * Check if a module URL is a css node module
12352
+ *
12353
+ * @param url to check
12354
+ * @returns whether or not it's a Css node module
12355
+ */
12182
12356
  const isCssNodeModule$1 = (url) => {
12183
12357
  return url.startsWith('~');
12184
12358
  };
12359
+ /**
12360
+ * Check if a given import is a local import or not (i.e. check that it
12361
+ * is not importing from some other domain)
12362
+ *
12363
+ * @param srcImport the import to check
12364
+ * @returns whether it's local or not
12365
+ */
12185
12366
  const isLocalCssImport$1 = (srcImport) => {
12186
12367
  srcImport = srcImport.toLowerCase();
12187
12368
  if (srcImport.includes('url(')) {
@@ -12194,6 +12375,13 @@ const isLocalCssImport$1 = (srcImport) => {
12194
12375
  }
12195
12376
  return true;
12196
12377
  };
12378
+ /**
12379
+ * Given a file path and a mode name, create an appropriate variable name
12380
+ *
12381
+ * @param filePath the path we want to use
12382
+ * @param modeName the name for the current style mode (i.e. `md` or `ios` on Navify)
12383
+ * @returns an appropriate Css var name
12384
+ */
12197
12385
  const createCssVarName = (filePath, modeName) => {
12198
12386
  let varName = path$5.basename(filePath);
12199
12387
  if (modeName && modeName !== DEFAULT_STYLE_MODE && !varName.includes(modeName)) {
@@ -16185,6 +16373,9 @@ class MockElement extends MockNode {
16185
16373
  this.shadowRoot = shadowRoot;
16186
16374
  return shadowRoot;
16187
16375
  }
16376
+ blur() {
16377
+ /**/
16378
+ }
16188
16379
  get shadowRoot() {
16189
16380
  return this.__shadowRoot || null;
16190
16381
  }
@@ -16253,6 +16444,7 @@ class MockElement extends MockNode {
16253
16444
  get firstElementChild() {
16254
16445
  return this.children[0] || null;
16255
16446
  }
16447
+ focus(_options) { }
16256
16448
  getAttribute(attrName) {
16257
16449
  if (attrName === 'style') {
16258
16450
  if (this.__style != null && this.__style.length > 0) {
@@ -17156,7 +17348,28 @@ function createElementNS(ownerDocument, namespaceURI, tagName) {
17156
17348
  return createElement(ownerDocument, tagName);
17157
17349
  }
17158
17350
  else if (namespaceURI === 'http://www.w3.org/2000/svg') {
17159
- return new MockSVGElement(ownerDocument, tagName);
17351
+ switch (tagName.toLowerCase()) {
17352
+ case 'text':
17353
+ case 'tspan':
17354
+ case 'tref':
17355
+ case 'altglyph':
17356
+ case 'textpath':
17357
+ return new MockSVGTextContentElement(ownerDocument, tagName);
17358
+ case 'circle':
17359
+ case 'ellipse':
17360
+ case 'image':
17361
+ case 'line':
17362
+ case 'path':
17363
+ case 'polygon':
17364
+ case 'polyline':
17365
+ case 'rect':
17366
+ case 'use':
17367
+ return new MockSVGGraphicsElement(ownerDocument, tagName);
17368
+ case 'svg':
17369
+ return new MockSVGSVGElement(ownerDocument, tagName);
17370
+ default:
17371
+ return new MockSVGElement(ownerDocument, tagName);
17372
+ }
17160
17373
  }
17161
17374
  else {
17162
17375
  return new MockElement(ownerDocument, tagName);
@@ -17303,6 +17516,98 @@ class MockScriptElement extends MockHTMLElement {
17303
17516
  patchPropAttributes(MockScriptElement.prototype, {
17304
17517
  type: String,
17305
17518
  });
17519
+ class MockDOMMatrix {
17520
+ constructor() {
17521
+ this.a = 1;
17522
+ this.b = 0;
17523
+ this.c = 0;
17524
+ this.d = 1;
17525
+ this.e = 0;
17526
+ this.f = 0;
17527
+ this.m11 = 1;
17528
+ this.m12 = 0;
17529
+ this.m13 = 0;
17530
+ this.m14 = 0;
17531
+ this.m21 = 0;
17532
+ this.m22 = 1;
17533
+ this.m23 = 0;
17534
+ this.m24 = 0;
17535
+ this.m31 = 0;
17536
+ this.m32 = 0;
17537
+ this.m33 = 1;
17538
+ this.m34 = 0;
17539
+ this.m41 = 0;
17540
+ this.m42 = 0;
17541
+ this.m43 = 0;
17542
+ this.m44 = 1;
17543
+ this.is2D = true;
17544
+ this.isIdentity = true;
17545
+ }
17546
+ static fromMatrix() {
17547
+ return new MockDOMMatrix();
17548
+ }
17549
+ inverse() {
17550
+ return new MockDOMMatrix();
17551
+ }
17552
+ flipX() {
17553
+ return new MockDOMMatrix();
17554
+ }
17555
+ flipY() {
17556
+ return new MockDOMMatrix();
17557
+ }
17558
+ multiply() {
17559
+ return new MockDOMMatrix();
17560
+ }
17561
+ rotate() {
17562
+ return new MockDOMMatrix();
17563
+ }
17564
+ rotateAxisAngle() {
17565
+ return new MockDOMMatrix();
17566
+ }
17567
+ rotateFromVector() {
17568
+ return new MockDOMMatrix();
17569
+ }
17570
+ scale() {
17571
+ return new MockDOMMatrix();
17572
+ }
17573
+ scaleNonUniform() {
17574
+ return new MockDOMMatrix();
17575
+ }
17576
+ skewX() {
17577
+ return new MockDOMMatrix();
17578
+ }
17579
+ skewY() {
17580
+ return new MockDOMMatrix();
17581
+ }
17582
+ toJSON() { }
17583
+ toString() { }
17584
+ transformPoint() {
17585
+ return new MockDOMPoint();
17586
+ }
17587
+ translate() {
17588
+ return new MockDOMMatrix();
17589
+ }
17590
+ }
17591
+ class MockDOMPoint {
17592
+ constructor() {
17593
+ this.w = 1;
17594
+ this.x = 0;
17595
+ this.y = 0;
17596
+ this.z = 0;
17597
+ }
17598
+ toJSON() { }
17599
+ matrixTransform() {
17600
+ return new MockDOMMatrix();
17601
+ }
17602
+ }
17603
+ class MockSVGRect {
17604
+ constructor() {
17605
+ this.height = 10;
17606
+ this.width = 10;
17607
+ this.x = 0;
17608
+ this.y = 0;
17609
+ }
17610
+ }
17306
17611
  class MockStyleElement extends MockHTMLElement {
17307
17612
  constructor(ownerDocument) {
17308
17613
  super(ownerDocument, 'style');
@@ -17335,9 +17640,6 @@ class MockSVGElement extends MockElement {
17335
17640
  get viewportElement() {
17336
17641
  return null;
17337
17642
  }
17338
- focus() {
17339
- /**/
17340
- }
17341
17643
  onunload() {
17342
17644
  /**/
17343
17645
  }
@@ -17355,6 +17657,27 @@ class MockSVGElement extends MockElement {
17355
17657
  return 0;
17356
17658
  }
17357
17659
  }
17660
+ class MockSVGGraphicsElement extends MockSVGElement {
17661
+ getBBox(_options) {
17662
+ return new MockSVGRect();
17663
+ }
17664
+ getCTM() {
17665
+ return new MockDOMMatrix();
17666
+ }
17667
+ getScreenCTM() {
17668
+ return new MockDOMMatrix();
17669
+ }
17670
+ }
17671
+ class MockSVGSVGElement extends MockSVGGraphicsElement {
17672
+ createSVGPoint() {
17673
+ return new MockDOMPoint();
17674
+ }
17675
+ }
17676
+ class MockSVGTextContentElement extends MockSVGGraphicsElement {
17677
+ getComputedTextLength() {
17678
+ return 0;
17679
+ }
17680
+ }
17358
17681
  class MockBaseElement extends MockHTMLElement {
17359
17682
  constructor(ownerDocument) {
17360
17683
  super(ownerDocument, 'base');
@@ -19102,48 +19425,88 @@ const emptyOutputTargets = async (config, compilerCtx, buildCtx) => {
19102
19425
  timeSpan.finish('cleaning dirs finished');
19103
19426
  };
19104
19427
 
19428
+ /**
19429
+ * Parse CSS imports into an object which contains a manifest of imports and a
19430
+ * stylesheet with all imports resolved and concatenated.
19431
+ *
19432
+ * @param config the current config
19433
+ * @param compilerCtx the compiler context (we need filesystem access)
19434
+ * @param buildCtx the build context, we'll need access to diagnostics
19435
+ * @param srcFilePath the source filepath
19436
+ * @param resolvedFilePath the resolved filepath
19437
+ * @param styleText style text we start with
19438
+ * @param styleDocs optional array of style document objects
19439
+ * @returns an object with concatenated styleText and imports
19440
+ */
19105
19441
  const parseCssImports = async (config, compilerCtx, buildCtx, srcFilePath, resolvedFilePath, styleText, styleDocs) => {
19106
19442
  const isCssEntry = resolvedFilePath.toLowerCase().endsWith('.css');
19107
19443
  const allCssImports = [];
19108
- const concatStyleText = await updateCssImports(config, compilerCtx, buildCtx, isCssEntry, srcFilePath, resolvedFilePath, styleText, allCssImports, new Set(), styleDocs);
19444
+ // a Set of previously-resolved file paths that we add to as we traverse the
19445
+ // import tree (to avoid a possible circular dependency and infinite loop)
19446
+ const resolvedFilePaths = new Set();
19447
+ const concatStyleText = await resolveAndFlattenImports(srcFilePath, resolvedFilePath, styleText);
19109
19448
  return {
19110
19449
  imports: allCssImports,
19111
19450
  styleText: concatStyleText,
19112
19451
  };
19113
- };
19114
- const updateCssImports = async (config, compilerCtx, buildCtx, isCssEntry, srcFilePath, resolvedFilePath, styleText, allCssImports, noLoop, styleDocs) => {
19115
- if (noLoop.has(resolvedFilePath)) {
19116
- return styleText;
19117
- }
19118
- noLoop.add(resolvedFilePath);
19119
- if (styleDocs != null) {
19120
- parseStyleDocs(styleDocs, styleText);
19121
- }
19122
- const cssImports = await getCssImports(config, compilerCtx, buildCtx, resolvedFilePath, styleText);
19123
- if (cssImports.length === 0) {
19124
- return styleText;
19125
- }
19126
- for (const cssImport of cssImports) {
19127
- if (!allCssImports.includes(cssImport.filePath)) {
19128
- allCssImports.push(cssImport.filePath);
19452
+ /**
19453
+ * Resolve and flatten all imports for a given CSS file, recursively crawling
19454
+ * the tree of imports to resolve them all and produce a concatenated
19455
+ * stylesheet. We declare this function here, within `parseCssImports`, in order
19456
+ * to get access to `compilerCtx`, `buildCtx`, and more without having to pass
19457
+ * a whole bunch of arguments.
19458
+ *
19459
+ * @param srcFilePath the source filepath
19460
+ * @param resolvedFilePath the resolved filepath
19461
+ * @param styleText style text we start with*
19462
+ * @returns concatenated styles assembled from the various imported stylesheets
19463
+ */
19464
+ async function resolveAndFlattenImports(srcFilePath, resolvedFilePath, styleText) {
19465
+ // if we've seen this path before we early return
19466
+ if (resolvedFilePaths.has(resolvedFilePath)) {
19467
+ return styleText;
19468
+ }
19469
+ resolvedFilePaths.add(resolvedFilePath);
19470
+ if (styleDocs != null) {
19471
+ parseStyleDocs(styleDocs, styleText);
19472
+ }
19473
+ const cssImports = await getCssImports(config, compilerCtx, buildCtx, resolvedFilePath, styleText);
19474
+ if (cssImports.length === 0) {
19475
+ return styleText;
19476
+ }
19477
+ // add any newly-found imports to the 'global' list
19478
+ for (const cssImport of cssImports) {
19479
+ if (!allCssImports.includes(cssImport.filePath)) {
19480
+ allCssImports.push(cssImport.filePath);
19481
+ }
19129
19482
  }
19130
- }
19131
- await Promise.all(cssImports.map(async (cssImportData) => {
19132
- await concatCssImport(config, compilerCtx, buildCtx, isCssEntry, srcFilePath, cssImportData, allCssImports, noLoop, styleDocs);
19133
- }));
19134
- return replaceImportDeclarations(styleText, cssImports, isCssEntry);
19135
- };
19136
- const concatCssImport = async (config, compilerCtx, buildCtx, isCssEntry, srcFilePath, cssImportData, allCssImports, noLoop, styleDocs) => {
19137
- cssImportData.styleText = await loadStyleText(compilerCtx, cssImportData);
19138
- if (typeof cssImportData.styleText === 'string') {
19139
- cssImportData.styleText = await updateCssImports(config, compilerCtx, buildCtx, isCssEntry, cssImportData.filePath, cssImportData.filePath, cssImportData.styleText, allCssImports, noLoop, styleDocs);
19140
- }
19141
- else {
19142
- const err = buildError(buildCtx.diagnostics);
19143
- err.messageText = `Unable to read css import: ${cssImportData.srcImport}`;
19144
- err.absFilePath = srcFilePath;
19483
+ // Recur down the tree of CSS imports, resolving all the imports in
19484
+ // the children of the current file (and, by extension, in their children
19485
+ // and so on)
19486
+ await Promise.all(cssImports.map(async (cssImportData) => {
19487
+ cssImportData.styleText = await loadStyleText(compilerCtx, cssImportData);
19488
+ if (typeof cssImportData.styleText === 'string') {
19489
+ cssImportData.styleText = await resolveAndFlattenImports(cssImportData.filePath, cssImportData.filePath, cssImportData.styleText);
19490
+ }
19491
+ else {
19492
+ // we had some error loading the file from disk, so write a diagnostic
19493
+ const err = buildError(buildCtx.diagnostics);
19494
+ err.messageText = `Unable to read css import: ${cssImportData.srcImport}`;
19495
+ err.absFilePath = srcFilePath;
19496
+ }
19497
+ }));
19498
+ // replace import statements with the actual CSS code in children modules
19499
+ return replaceImportDeclarations(styleText, cssImports, isCssEntry);
19145
19500
  }
19146
19501
  };
19502
+ /**
19503
+ * Load the style text for a CSS file from disk, based on the filepaths set in
19504
+ * our import data.
19505
+ *
19506
+ * @param compilerCtx the compiler context
19507
+ * @param cssImportData the import data for the file we want to read
19508
+ * @returns the contents of the file, if it can be read without error
19509
+ */
19147
19510
  const loadStyleText = async (compilerCtx, cssImportData) => {
19148
19511
  let styleText = null;
19149
19512
  try {
@@ -19159,7 +19522,18 @@ const loadStyleText = async (compilerCtx, cssImportData) => {
19159
19522
  }
19160
19523
  return styleText;
19161
19524
  };
19525
+ /**
19526
+ * Get a manifest of all the CSS imports in a given CSS file
19527
+ *
19528
+ * @param config the current config
19529
+ * @param compilerCtx the compiler context (we need the filesystem)
19530
+ * @param buildCtx the build context, in case we need to set a diagnostic
19531
+ * @param filePath the filepath we're working with
19532
+ * @param styleText the CSS for which we want to retrieve import data
19533
+ * @returns a Promise wrapping a list of CSS import data objects
19534
+ */
19162
19535
  const getCssImports = async (config, compilerCtx, buildCtx, filePath, styleText) => {
19536
+ var _a;
19163
19537
  const imports = [];
19164
19538
  if (!styleText.includes('@import')) {
19165
19539
  // no @import at all, so don't bother
@@ -19167,13 +19541,14 @@ const getCssImports = async (config, compilerCtx, buildCtx, filePath, styleText)
19167
19541
  }
19168
19542
  styleText = stripCssComments(styleText);
19169
19543
  const dir = dirname(filePath);
19170
- const importeeExt = filePath.split('.').pop().toLowerCase();
19544
+ const importeeExt = ((_a = filePath.split('.').pop()) !== null && _a !== void 0 ? _a : '').toLowerCase();
19171
19545
  let r;
19172
19546
  const IMPORT_RE = /(@import)\s+(url\()?\s?(.*?)\s?\)?([^;]*);?/gi;
19173
19547
  while ((r = IMPORT_RE.exec(styleText))) {
19174
19548
  const cssImportData = {
19175
19549
  srcImport: r[0],
19176
19550
  url: r[4].replace(/[\"\'\)]/g, ''),
19551
+ filePath: '',
19177
19552
  };
19178
19553
  if (!isLocalCssImport(cssImportData.srcImport)) {
19179
19554
  // do nothing for @import url(http://external.css)
@@ -19200,7 +19575,10 @@ const getCssImports = async (config, compilerCtx, buildCtx, filePath, styleText)
19200
19575
  cssImportData.altFilePath = normalizePath$1(join(dirPath, fileName));
19201
19576
  }
19202
19577
  }
19203
- if (typeof cssImportData.filePath === 'string') {
19578
+ // we set `filePath` to `""` when the object is created above, so if it
19579
+ // hasn't been changed in the intervening conditionals then we didn't resolve
19580
+ // a filepath for it.
19581
+ if (cssImportData.filePath !== '') {
19204
19582
  imports.push(cssImportData);
19205
19583
  }
19206
19584
  }
@@ -19242,6 +19620,16 @@ const isLocalCssImport = (srcImport) => {
19242
19620
  }
19243
19621
  return true;
19244
19622
  };
19623
+ /**
19624
+ * Replace import declarations (like '@import "foobar";') with the actual CSS
19625
+ * written in the imported module, allowing us to produce a single file from a
19626
+ * tree of stylesheets.
19627
+ *
19628
+ * @param styleText the text within which we want to replace @import statements
19629
+ * @param cssImports information about imported modules
19630
+ * @param isCssEntry whether we're dealing with a CSS file
19631
+ * @returns an updated string with the requisite substitutions
19632
+ */
19245
19633
  const replaceImportDeclarations = (styleText, cssImports, isCssEntry) => {
19246
19634
  for (const cssImport of cssImports) {
19247
19635
  if (isCssEntry) {
@@ -41575,6 +41963,7 @@ const createComponentExport = (cmp) => {
41575
41963
  * using the `dist-custom-elements` output target may have a single 'entry point' for each file containing a component.
41576
41964
  * Each of those files will be independently resolved and loaded by this plugin for further processing by Rollup later
41577
41965
  * in the bundling process.
41966
+ *
41578
41967
  * @param entries the Rindo project files to process. It should be noted that the keys in this object may not
41579
41968
  * necessarily be an absolute or relative path to a file, but may be a Rollup Virtual Module (which begin with \0).
41580
41969
  * @returns the rollup plugin that loads and process a Rindo project's entry points
@@ -41743,9 +42132,9 @@ const fetchUrlSync = (url) => {
41743
42132
  return undefined;
41744
42133
  };
41745
42134
 
41746
- const patchTsSystemFileSystem = (config, rindoSys, inMemoryFs, tsSys) => {
42135
+ const patchTsSystemFileSystem = (config, compilerSys, inMemoryFs, tsSys) => {
41747
42136
  const realpath = (path) => {
41748
- const rp = rindoSys.realpathSync(path);
42137
+ const rp = compilerSys.realpathSync(path);
41749
42138
  if (isString$1(rp)) {
41750
42139
  return rp;
41751
42140
  }
@@ -41753,7 +42142,7 @@ const patchTsSystemFileSystem = (config, rindoSys, inMemoryFs, tsSys) => {
41753
42142
  };
41754
42143
  const getAccessibleFileSystemEntries = (path) => {
41755
42144
  try {
41756
- const entries = rindoSys.readDirSync(path || '.').sort();
42145
+ const entries = compilerSys.readDirSync(path || '.').sort();
41757
42146
  const files = [];
41758
42147
  const directories = [];
41759
42148
  for (const absPath of entries) {
@@ -41778,13 +42167,13 @@ const patchTsSystemFileSystem = (config, rindoSys, inMemoryFs, tsSys) => {
41778
42167
  }
41779
42168
  };
41780
42169
  tsSys.createDirectory = (p) => {
41781
- rindoSys.createDirSync(p, { recursive: true });
42170
+ compilerSys.createDirSync(p, { recursive: true });
41782
42171
  };
41783
42172
  tsSys.directoryExists = (p) => {
41784
42173
  const s = inMemoryFs.statSync(p);
41785
42174
  return s.isDirectory;
41786
42175
  };
41787
- tsSys.exit = rindoSys.exit;
42176
+ tsSys.exit = compilerSys.exit;
41788
42177
  tsSys.fileExists = (p) => {
41789
42178
  let filePath = p;
41790
42179
  if (isRemoteUrl(p)) {
@@ -41793,17 +42182,17 @@ const patchTsSystemFileSystem = (config, rindoSys, inMemoryFs, tsSys) => {
41793
42182
  const s = inMemoryFs.statSync(filePath);
41794
42183
  return !!(s && s.isFile);
41795
42184
  };
41796
- tsSys.getCurrentDirectory = rindoSys.getCurrentDirectory;
41797
- tsSys.getExecutingFilePath = rindoSys.getCompilerExecutingPath;
42185
+ tsSys.getCurrentDirectory = compilerSys.getCurrentDirectory;
42186
+ tsSys.getExecutingFilePath = compilerSys.getCompilerExecutingPath;
41798
42187
  tsSys.getDirectories = (p) => {
41799
- const items = rindoSys.readDirSync(p);
42188
+ const items = compilerSys.readDirSync(p);
41800
42189
  return items.filter((itemPath) => {
41801
42190
  const s = inMemoryFs.statSync(itemPath);
41802
42191
  return !!(s && s.exists && s.isDirectory);
41803
42192
  });
41804
42193
  };
41805
42194
  tsSys.readDirectory = (path, extensions, exclude, include, depth) => {
41806
- const cwd = rindoSys.getCurrentDirectory();
42195
+ const cwd = compilerSys.getCurrentDirectory();
41807
42196
  // TODO: Replace `matchFiles` with a function that is publicly exposed
41808
42197
  return t.matchFiles(path, extensions, exclude, include, IS_CASE_SENSITIVE_FILE_NAMES, cwd, depth, getAccessibleFileSystemEntries, realpath);
41809
42198
  };
@@ -41830,9 +42219,9 @@ const patchTsSystemFileSystem = (config, rindoSys, inMemoryFs, tsSys) => {
41830
42219
  tsSys.writeFile = (p, data) => inMemoryFs.writeFile(p, data);
41831
42220
  return tsSys;
41832
42221
  };
41833
- const patchTsSystemWatch = (rindoSys, tsSys) => {
42222
+ const patchTsSystemWatch = (compilerSystem, tsSys) => {
41834
42223
  tsSys.watchDirectory = (p, cb, recursive) => {
41835
- const watcher = rindoSys.watchDirectory(p, (filePath) => {
42224
+ const watcher = compilerSystem.watchDirectory(p, (filePath) => {
41836
42225
  cb(filePath);
41837
42226
  }, recursive);
41838
42227
  return {
@@ -41842,7 +42231,7 @@ const patchTsSystemWatch = (rindoSys, tsSys) => {
41842
42231
  };
41843
42232
  };
41844
42233
  tsSys.watchFile = (p, cb) => {
41845
- const watcher = rindoSys.watchFile(p, (filePath, eventKind) => {
42234
+ const watcher = compilerSystem.watchFile(p, (filePath, eventKind) => {
41846
42235
  if (eventKind === 'fileAdd') {
41847
42236
  cb(filePath, t.FileWatcherEventKind.Created);
41848
42237
  }
@@ -42050,7 +42439,7 @@ const createCustomResolverSync = (sys, inMemoryFs, exts) => {
42050
42439
  * https://github.com/DefinitelyTyped/DefinitelyTyped/blob/d121716ed123957f6a86f8985eb013fcaddab345/types/node/globals.d.ts#L183-L188
42051
42440
  * in mind.
42052
42441
  * @param err the entity to check the type of
42053
- * @return true if the provided value is an instance of `ErrnoException`, `false` otherwise
42442
+ * @returns true if the provided value is an instance of `ErrnoException`, `false` otherwise
42054
42443
  */
42055
42444
  function isErrnoException(err) {
42056
42445
  return err instanceof Error && err.hasOwnProperty('code');
@@ -56093,6 +56482,9 @@ const updateRindoCoreImports = (updatedCoreImportPath) => {
56093
56482
  };
56094
56483
  };
56095
56484
  };
56485
+ /**
56486
+ * A set of imports which we don't want to remove from an output file
56487
+ */
56096
56488
  const KEEP_IMPORTS = new Set([
56097
56489
  'h',
56098
56490
  'setMode',
@@ -56112,37 +56504,75 @@ const KEEP_IMPORTS = new Set([
56112
56504
  'setErrorHandler',
56113
56505
  ]);
56114
56506
 
56507
+ /**
56508
+ * Main output target function for `dist-custom-elements`. This function just
56509
+ * does some organizational work to call the other functions in this module,
56510
+ * which do actual work of generating the rollup configuration, creating an
56511
+ * entry chunk, running, the build, etc.
56512
+ *
56513
+ * @param config the user-supplied compiler configuration we're using
56514
+ * @param compilerCtx the current compiler context
56515
+ * @param buildCtx the current build context
56516
+ * @returns an empty Promise which won't resolve until the work is done!
56517
+ */
56115
56518
  const outputCustomElements = async (config, compilerCtx, buildCtx) => {
56519
+ var _a;
56116
56520
  if (!config.buildDist) {
56117
56521
  return;
56118
56522
  }
56119
- const outputTargets = config.outputTargets.filter(isOutputTargetDistCustomElements);
56523
+ const outputTargets = ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : []).filter(isOutputTargetDistCustomElements);
56120
56524
  if (outputTargets.length === 0) {
56121
56525
  return;
56122
56526
  }
56123
56527
  const bundlingEventMessage = 'generate custom elements';
56124
56528
  const timespan = buildCtx.createTimeSpan(`${bundlingEventMessage} started`);
56125
- await Promise.all(outputTargets.map((o) => bundleCustomElements$1(config, compilerCtx, buildCtx, o)));
56529
+ await Promise.all(outputTargets.map((target) => bundleCustomElements$1(config, compilerCtx, buildCtx, target)));
56126
56530
  timespan.finish(`${bundlingEventMessage} finished`);
56127
56531
  };
56532
+ /**
56533
+ * Get bundle options for our current build and compiler context which we'll use
56534
+ * to generate a Rollup build and so on.
56535
+ *
56536
+ * @param config user-supplied Rindo configuration
56537
+ * @param buildCtx the current build context
56538
+ * @param compilerCtx the current compiler context
56539
+ * @param outputTarget the outputTarget we're currently dealing with
56540
+ * @returns bundle options suitable for generating a rollup configuration
56541
+ */
56542
+ const getBundleOptions = (config, buildCtx, compilerCtx, outputTarget) => ({
56543
+ id: 'customElements',
56544
+ platform: 'client',
56545
+ conditionals: getCustomElementsBuildConditionals(config, buildCtx.components),
56546
+ customTransformers: getCustomElementCustomTransformer(config, compilerCtx, buildCtx.components, outputTarget),
56547
+ externalRuntime: !!outputTarget.externalRuntime,
56548
+ inlineWorkers: true,
56549
+ inputs: {
56550
+ // Here we prefix our index chunk with '\0' to tell Rollup that we're
56551
+ // going to be using virtual modules with this module. A leading '\0'
56552
+ // prevents other plugins from messing with the module. We generate a
56553
+ // string for the index chunk below in the `loader` property.
56554
+ //
56555
+ // @see {@link https://rollupjs.org/guide/en/#conventions} for more info.
56556
+ index: '\0core',
56557
+ },
56558
+ loader: {
56559
+ '\0core': generateEntryPoint$1(outputTarget),
56560
+ },
56561
+ inlineDynamicImports: outputTarget.inlineDynamicImports,
56562
+ preserveEntrySignatures: 'allow-extension',
56563
+ });
56564
+ /**
56565
+ * Get bundle options for rollup, run the rollup build, optionally minify the
56566
+ * output, and write files to disk.
56567
+ * @param config user-supplied Rindo configuration
56568
+ * @param buildCtx the current build context
56569
+ * @param compilerCtx the current compiler context
56570
+ * @param outputTarget the outputTarget we're currently dealing with
56571
+ * @returns an empty promise
56572
+ */
56128
56573
  const bundleCustomElements$1 = async (config, compilerCtx, buildCtx, outputTarget) => {
56129
56574
  try {
56130
- const bundleOpts = {
56131
- id: 'customElements',
56132
- platform: 'client',
56133
- conditionals: getCustomElementsBuildConditionals(config, buildCtx.components),
56134
- customTransformers: getCustomElementCustomTransformer(config, compilerCtx, buildCtx.components, outputTarget),
56135
- externalRuntime: !!outputTarget.externalRuntime,
56136
- inlineWorkers: true,
56137
- inputs: {
56138
- index: '\0core',
56139
- },
56140
- loader: {
56141
- '\0core': generateEntryPoint$1(outputTarget),
56142
- },
56143
- inlineDynamicImports: outputTarget.inlineDynamicImports,
56144
- preserveEntrySignatures: 'allow-extension',
56145
- };
56575
+ const bundleOpts = getBundleOptions(config, buildCtx, compilerCtx, outputTarget);
56146
56576
  addCustomElementInputs(buildCtx, bundleOpts);
56147
56577
  const build = await bundleOutput(config, compilerCtx, buildCtx, bundleOpts);
56148
56578
  if (build) {
@@ -56155,6 +56585,18 @@ const bundleCustomElements$1 = async (config, compilerCtx, buildCtx, outputTarge
56155
56585
  hoistTransitiveImports: false,
56156
56586
  preferConst: true,
56157
56587
  });
56588
+ // the output target should have been validated at this point - as a result, we expect this field
56589
+ // to have been backfilled if it wasn't provided
56590
+ const outputTargetDir = outputTarget.dir;
56591
+ // besides, if it isn't here we do a diagnostic and an early return
56592
+ if (!isString$1(outputTargetDir)) {
56593
+ buildCtx.diagnostics.push({
56594
+ level: 'error',
56595
+ type: 'build',
56596
+ messageText: 'dist-custom-elements output target provided with no output target directory!',
56597
+ });
56598
+ return;
56599
+ }
56158
56600
  const minify = outputTarget.externalRuntime || outputTarget.minify !== true ? false : config.minifyJs;
56159
56601
  const files = rollupOutput.output.map(async (bundle) => {
56160
56602
  if (bundle.type === 'chunk') {
@@ -56169,15 +56611,15 @@ const bundleCustomElements$1 = async (config, compilerCtx, buildCtx, outputTarge
56169
56611
  buildCtx.diagnostics.push(...optimizeResults.diagnostics);
56170
56612
  if (!hasError(optimizeResults.diagnostics) && typeof optimizeResults.output === 'string') {
56171
56613
  code = optimizeResults.output;
56172
- sourceMap = optimizeResults.sourceMap;
56173
56614
  }
56174
- if (sourceMap) {
56615
+ if (optimizeResults.sourceMap) {
56616
+ sourceMap = optimizeResults.sourceMap;
56175
56617
  code = code + getSourceMappingUrlForEndOfFile(bundle.fileName);
56176
- await compilerCtx.fs.writeFile(join(outputTarget.dir, bundle.fileName + '.map'), JSON.stringify(sourceMap), {
56618
+ await compilerCtx.fs.writeFile(join(outputTargetDir, bundle.fileName + '.map'), JSON.stringify(sourceMap), {
56177
56619
  outputTargetType: outputTarget.type,
56178
56620
  });
56179
56621
  }
56180
- await compilerCtx.fs.writeFile(join(outputTarget.dir, bundle.fileName), code, {
56622
+ await compilerCtx.fs.writeFile(join(outputTargetDir, bundle.fileName), code, {
56181
56623
  outputTargetType: outputTarget.type,
56182
56624
  });
56183
56625
  }
@@ -56196,6 +56638,8 @@ const bundleCustomElements$1 = async (config, compilerCtx, buildCtx, outputTarge
56196
56638
  */
56197
56639
  const addCustomElementInputs = (buildCtx, bundleOpts) => {
56198
56640
  const components = buildCtx.components;
56641
+ // an array to store the imports of these modules that we're going to add to our entry chunk
56642
+ const indexImports = [];
56199
56643
  components.forEach((cmp) => {
56200
56644
  const exp = [];
56201
56645
  const exportName = dashToPascalCase$1(cmp.tagName);
@@ -56204,16 +56648,25 @@ const addCustomElementInputs = (buildCtx, bundleOpts) => {
56204
56648
  const coreKey = `\0${exportName}`;
56205
56649
  if (cmp.isPlain) {
56206
56650
  exp.push(`export { ${importName} as ${exportName} } from '${cmp.sourceFilePath}';`);
56651
+ indexImports.push(`export { {${exportName} } from '${coreKey}';`);
56207
56652
  }
56208
56653
  else {
56209
56654
  // the `importName` may collide with the `exportName`, alias it just in case it does with `importAs`
56210
56655
  exp.push(`import { ${importName} as ${importAs}, defineCustomElement as cmpDefCustomEle } from '${cmp.sourceFilePath}';`);
56211
56656
  exp.push(`export const ${exportName} = ${importAs};`);
56212
56657
  exp.push(`export const defineCustomElement = cmpDefCustomEle;`);
56658
+ // Here we push an export (with a rename for `defineCustomElement` for
56659
+ // this component onto our array which references the `coreKey` (prefixed
56660
+ // with `\0`). We have to do this so that our import is referencing the
56661
+ // correct virtual module, if we instead referenced, for instance,
56662
+ // `cmp.sourceFilePath`, we would end up with duplicated modules in our
56663
+ // output.
56664
+ indexImports.push(`export { ${exportName}, defineCustomElement as defineCustomElement${exportName} } from '${coreKey}';`);
56213
56665
  }
56214
56666
  bundleOpts.inputs[cmp.tagName] = coreKey;
56215
56667
  bundleOpts.loader[coreKey] = exp.join('\n');
56216
56668
  });
56669
+ bundleOpts.loader['\0core'] += indexImports.join('\n');
56217
56670
  };
56218
56671
  /**
56219
56672
  * Generate the entrypoint (`index.ts` file) contents for the `dist-custom-elements` output target
@@ -56231,6 +56684,7 @@ const generateEntryPoint$1 = (outputTarget) => {
56231
56684
  /**
56232
56685
  * Get the series of custom transformers that will be applied to a Rindo project's source code during the TypeScript
56233
56686
  * transpilation process
56687
+ *
56234
56688
  * @param config the configuration for the Rindo project
56235
56689
  * @param compilerCtx the current compiler context
56236
56690
  * @param components the components that will be compiled as a part of the current build
@@ -58022,6 +58476,16 @@ const lazyComponentTransform = (compilerCtx, transformOpts) => {
58022
58476
  };
58023
58477
  };
58024
58478
 
58479
+ /**
58480
+ * Generate rollup output based on a rollup build and a series of options.
58481
+ *
58482
+ * @param build a rollup build
58483
+ * @param options output options for rollup
58484
+ * @param config a user-supplied configuration object
58485
+ * @param entryModules a list of entry modules, for checking which chunks
58486
+ * contain components
58487
+ * @returns a Promise wrapping either build results or `null`
58488
+ */
58025
58489
  const generateRollupOutput = async (build, options, config, entryModules) => {
58026
58490
  if (build == null) {
58027
58491
  return null;
@@ -58029,7 +58493,7 @@ const generateRollupOutput = async (build, options, config, entryModules) => {
58029
58493
  const { output } = await build.generate(options);
58030
58494
  return output.map((chunk) => {
58031
58495
  if (chunk.type === 'chunk') {
58032
- const isCore = Object.keys(chunk.modules).some((m) => m.includes('@rindo/core'));
58496
+ const isCore = Object.keys(chunk.modules).some((m) => m.includes(RINDO_CORE_ID));
58033
58497
  return {
58034
58498
  type: 'chunk',
58035
58499
  fileName: chunk.fileName,
@@ -58528,7 +58992,8 @@ const getSystemLoader = async (config, compilerCtx, corePath, includePolyfills)
58528
58992
 
58529
58993
  var resourcesUrl = scriptElm ? scriptElm.getAttribute('data-resources-url') || scriptElm.src : '';
58530
58994
  var start = function() {
58531
- var url = new URL('${corePath}', new URL(resourcesUrl, window.location.origin));
58995
+ // if src is not present then origin is "null", and new URL() throws TypeError: Failed to construct 'URL': Invalid base URL
58996
+ var url = new URL('${corePath}', new URL(resourcesUrl, window.location.origin !== 'null' ? window.location.origin : undefined));
58532
58997
  System.import(url.href);
58533
58998
  };
58534
58999
 
@@ -60222,29 +60687,38 @@ const relDts$1 = (fromPath, dtsPath) => {
60222
60687
  * @param config the Rindo configuration associated with the project being compiled
60223
60688
  * @param compilerCtx the current compiler context
60224
60689
  * @param buildCtx the context associated with the current build
60225
- * @param distDtsFilePath the path to a type declaration file (.d.ts) that is being generated for the output target.
60226
- * This path is not necessarily the `components.d.ts` file that is found in the root of a project's `src` directory.
60690
+ * @param typesDir the path to the directory where type declarations are saved
60227
60691
  */
60228
- const generateCustomElementsTypes = async (config, compilerCtx, buildCtx, distDtsFilePath) => {
60229
- const outputTargets = config.outputTargets.filter(isOutputTargetDistCustomElements);
60230
- await Promise.all(outputTargets.map((outputTarget) => generateCustomElementsTypesOutput(config, compilerCtx, buildCtx, distDtsFilePath, outputTarget)));
60692
+ const generateCustomElementsTypes = async (config, compilerCtx, buildCtx, typesDir) => {
60693
+ var _a;
60694
+ const outputTargets = ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : []).filter(isOutputTargetDistCustomElements);
60695
+ await Promise.all(outputTargets.map((outputTarget) => generateCustomElementsTypesOutput(config, compilerCtx, buildCtx, typesDir, outputTarget)));
60231
60696
  };
60232
60697
  /**
60233
60698
  * Generates types for a single `dist-custom-elements` output target definition in a Rindo project's configuration
60699
+ *
60234
60700
  * @param config the Rindo configuration associated with the project being compiled
60235
60701
  * @param compilerCtx the current compiler context
60236
60702
  * @param buildCtx the context associated with the current build
60237
- * @param distDtsFilePath the path to a type declaration file (.d.ts) that is being generated for the output target.
60238
- * This path is not necessarily the `components.d.ts` file that is found in the root of a project's `src` directory.
60703
+ * @param typesDir path to the directory where type declarations are saved
60239
60704
  * @param outputTarget the output target for which types are being currently generated
60240
60705
  */
60241
- const generateCustomElementsTypesOutput = async (config, compilerCtx, buildCtx, distDtsFilePath, outputTarget) => {
60706
+ const generateCustomElementsTypesOutput = async (config, compilerCtx, buildCtx, typesDir, outputTarget) => {
60707
+ // the path where we're going to write the typedef for the whole dist-custom-elements output
60242
60708
  const customElementsDtsPath = join(outputTarget.dir, 'index.d.ts');
60243
- const componentsDtsRelPath = relDts(outputTarget.dir, distDtsFilePath);
60709
+ // the directory where types for the individual components are written
60710
+ const componentsTypeDirectoryPath = relative$1(outputTarget.dir, join(typesDir, 'components'));
60711
+ const components = buildCtx.components.filter((m) => !m.isCollectionDependency);
60244
60712
  const code = [
60245
60713
  `/* ${config.namespace} custom elements */`,
60246
- ``,
60247
- `import type { Components, JSX } from "${componentsDtsRelPath}";`,
60714
+ ...components.map((component) => {
60715
+ const exportName = dashToPascalCase$1(component.tagName);
60716
+ const importName = component.componentClassName;
60717
+ // typedefs for individual components can be found under paths like
60718
+ // $TYPES_DIR/components/my-component/my-component.d.ts
60719
+ const componentDTSPath = join(componentsTypeDirectoryPath, component.tagName, component.tagName);
60720
+ return `export { ${importName} as ${exportName} } from '${componentDTSPath}';`;
60721
+ }),
60248
60722
  ``,
60249
60723
  `/**`,
60250
60724
  ` * Used to manually set the base path where assets can be found.`,
@@ -60264,10 +60738,8 @@ const generateCustomElementsTypesOutput = async (config, compilerCtx, buildCtx,
60264
60738
  ` rel?: (el: EventTarget, eventName: string, listener: EventListenerOrEventListenerObject, options: boolean | AddEventListenerOptions) => void;`,
60265
60739
  `}`,
60266
60740
  `export declare const setPlatformOptions: (opts: SetPlatformOptions) => void;`,
60267
- ``,
60268
- `export type { Components, JSX };`,
60269
- ``,
60270
60741
  ];
60742
+ const componentsDtsRelPath = relDts(outputTarget.dir, join(typesDir, 'components.d.ts'));
60271
60743
  const usersIndexJsPath = join(config.srcDir, 'index.ts');
60272
60744
  const hasUserIndex = await compilerCtx.fs.access(usersIndexJsPath);
60273
60745
  if (hasUserIndex) {
@@ -60280,7 +60752,6 @@ const generateCustomElementsTypesOutput = async (config, compilerCtx, buildCtx,
60280
60752
  await compilerCtx.fs.writeFile(customElementsDtsPath, code.join('\n') + `\n`, {
60281
60753
  outputTargetType: outputTarget.type,
60282
60754
  });
60283
- const components = buildCtx.components.filter((m) => !m.isCollectionDependency);
60284
60755
  await Promise.all(components.map(async (cmp) => {
60285
60756
  const dtsCode = generateCustomElementType(componentsDtsRelPath, cmp);
60286
60757
  const fileName = `${cmp.tagName}.d.ts`;
@@ -60354,20 +60825,21 @@ const generateTypesOutput = async (config, compilerCtx, buildCtx, outputTarget)
60354
60825
  const srcDtsFiles = srcDirItems.filter((srcItem) => srcItem.isFile && isDtsFile$1(srcItem.absPath));
60355
60826
  // Copy .d.ts files from src to dist
60356
60827
  // In addition, all references to @rindo/core are replaced
60357
- let distDtsFilePath;
60358
- await Promise.all(srcDtsFiles.map(async (srcDtsFile) => {
60828
+ const copiedDTSFilePaths = await Promise.all(srcDtsFiles.map(async (srcDtsFile) => {
60359
60829
  const relPath = relative$1(config.srcDir, srcDtsFile.absPath);
60360
60830
  const distPath = join(outputTarget.typesDir, relPath);
60361
60831
  const originalDtsContent = await compilerCtx.fs.readFile(srcDtsFile.absPath);
60362
60832
  const distDtsContent = updateRindoTypesImports(outputTarget.typesDir, distPath, originalDtsContent);
60363
60833
  await compilerCtx.fs.writeFile(distPath, distDtsContent);
60364
- distDtsFilePath = distPath;
60834
+ return distPath;
60365
60835
  }));
60836
+ const distDtsFilePath = copiedDTSFilePaths.slice(-1)[0];
60366
60837
  const distPath = outputTarget.typesDir;
60367
60838
  await generateAppTypes(config, compilerCtx, buildCtx, distPath);
60839
+ const { typesDir } = outputTarget;
60368
60840
  if (distDtsFilePath) {
60369
- await generateCustomElementsTypes(config, compilerCtx, buildCtx, distDtsFilePath);
60370
60841
  await generateCustomElementsBundleTypes(config, compilerCtx, buildCtx, distDtsFilePath);
60842
+ await generateCustomElementsTypes(config, compilerCtx, buildCtx, typesDir);
60371
60843
  }
60372
60844
  };
60373
60845
 
@@ -64162,37 +64634,76 @@ const filesChanged = (buildCtx) => {
64162
64634
  // files changed include updated, added and deleted
64163
64635
  return unique([...buildCtx.filesUpdated, ...buildCtx.filesAdded, ...buildCtx.filesDeleted]).sort();
64164
64636
  };
64165
- const scriptsAdded = (buildCtx) => {
64166
- // collect all the scripts that were added
64167
- return buildCtx.filesAdded
64168
- .filter((f) => {
64169
- return SCRIPT_EXT.some((ext) => f.endsWith(ext.toLowerCase()));
64170
- })
64171
- .map((f) => basename(f));
64172
- };
64173
- const scriptsDeleted = (buildCtx) => {
64174
- // collect all the scripts that were deleted
64175
- return buildCtx.filesDeleted
64176
- .filter((f) => {
64177
- return SCRIPT_EXT.some((ext) => f.endsWith(ext.toLowerCase()));
64178
- })
64179
- .map((f) => basename(f));
64180
- };
64181
- const hasScriptChanges = (buildCtx) => {
64182
- return buildCtx.filesChanged.some((f) => {
64183
- const ext = getExt(f);
64184
- return SCRIPT_EXT.includes(ext);
64185
- });
64186
- };
64187
- const hasStyleChanges = (buildCtx) => {
64188
- return buildCtx.filesChanged.some((f) => {
64189
- const ext = getExt(f);
64190
- return STYLE_EXT.includes(ext);
64191
- });
64192
- };
64637
+ /**
64638
+ * Unary helper function mapping string to string and wrapping `basename`,
64639
+ * which normally takes two string arguments. This means it cannot be passed
64640
+ * to `Array.prototype.map`, but this little helper can!
64641
+ *
64642
+ * @param filePath a filepath to check out
64643
+ * @returns the basename for that filepath
64644
+ */
64645
+ const unaryBasename = (filePath) => basename(filePath);
64646
+ /**
64647
+ * Get the file extension for a path
64648
+ *
64649
+ * @param filePath a path
64650
+ * @returns the file extension (well, characters after the last `'.'`)
64651
+ */
64193
64652
  const getExt = (filePath) => filePath.split('.').pop().toLowerCase();
64653
+ /**
64654
+ * Script extensions which we want to be able to recognize
64655
+ */
64194
64656
  const SCRIPT_EXT = ['ts', 'tsx', 'js', 'jsx'];
64657
+ /**
64658
+ * Helper to check if a filepath has a script extension
64659
+ *
64660
+ * @param filePath a file extension
64661
+ * @returns whether the filepath has a script extension or not
64662
+ */
64663
+ const hasScriptExt = (filePath) => SCRIPT_EXT.includes(getExt(filePath));
64195
64664
  const STYLE_EXT = ['css', 'scss', 'sass', 'pcss', 'styl', 'stylus', 'less'];
64665
+ /**
64666
+ * Helper to check if a filepath has a style extension
64667
+ *
64668
+ * @param filePath a file extension to check
64669
+ * @returns whether the filepath has a style extension or not
64670
+ */
64671
+ const hasStyleExt = (filePath) => STYLE_EXT.includes(getExt(filePath));
64672
+ /**
64673
+ * Get all scripts from a build context that were added
64674
+ *
64675
+ * @param buildCtx the build context
64676
+ * @returns an array of filepaths that were added
64677
+ */
64678
+ const scriptsAdded = (buildCtx) => buildCtx.filesAdded.filter(hasScriptExt).map(unaryBasename);
64679
+ /**
64680
+ * Get all scripts from a build context that were deleted
64681
+ *
64682
+ * @param buildCtx the build context
64683
+ * @returns an array of deleted filepaths
64684
+ */
64685
+ const scriptsDeleted = (buildCtx) => buildCtx.filesDeleted.filter(hasScriptExt).map(unaryBasename);
64686
+ /**
64687
+ * Check whether a build has script changes
64688
+ *
64689
+ * @param buildCtx the build context
64690
+ * @returns whether or not there are script changes
64691
+ */
64692
+ const hasScriptChanges = (buildCtx) => buildCtx.filesChanged.some(hasScriptExt);
64693
+ /**
64694
+ * Check whether a build has style changes
64695
+ *
64696
+ * @param buildCtx the build context
64697
+ * @returns whether or not there are style changes
64698
+ */
64699
+ const hasStyleChanges = (buildCtx) => buildCtx.filesChanged.some(hasStyleExt);
64700
+ /**
64701
+ * Check whether a build has html changes
64702
+ *
64703
+ * @param config the current config
64704
+ * @param buildCtx the build context
64705
+ * @returns whether or not HTML files were changed
64706
+ */
64196
64707
  const hasHtmlChanges = (config, buildCtx) => {
64197
64708
  const anyHtmlChanged = buildCtx.filesChanged.some((f) => f.toLowerCase().endsWith('.html'));
64198
64709
  if (anyHtmlChanged) {
@@ -64407,15 +64918,14 @@ const updateCompilerCtxCache = (config, compilerCtx, path, kind) => {
64407
64918
  };
64408
64919
 
64409
64920
  const getConfig = (userConfig) => {
64410
- const config = { ...userConfig };
64411
- if (!config.logger) {
64412
- config.logger = createLogger();
64413
- }
64921
+ var _a, _b;
64922
+ const flags = (_a = userConfig.flags) !== null && _a !== void 0 ? _a : {};
64923
+ const logger = (_b = userConfig.logger) !== null && _b !== void 0 ? _b : createLogger();
64924
+ const config = { ...userConfig, flags, logger };
64414
64925
  if (!config.sys) {
64415
64926
  config.sys = createSystem({ logger: config.logger });
64416
64927
  }
64417
64928
  setPlatformPath(config.sys.platformPath);
64418
- config.flags = config.flags || {};
64419
64929
  if (config.flags.debug || config.flags.verbose) {
64420
64930
  config.logLevel = 'debug';
64421
64931
  }
@@ -64436,14 +64946,15 @@ const patchFs = (userSys) => {
64436
64946
 
64437
64947
  /**
64438
64948
  * Generate a Rindo compiler instance
64439
- * @param config a Rindo configuration to apply to the compiler instance
64949
+ * @param userConfig a user-provided a Rindo configuration to apply to the compiler instance
64440
64950
  * @returns a new instance of a Rindo compiler
64951
+ * @public
64441
64952
  */
64442
- const createCompiler = async (config) => {
64953
+ const createCompiler = async (userConfig) => {
64443
64954
  // actual compiler code
64444
64955
  // could be in a web worker on the browser
64445
64956
  // or the main thread in node
64446
- config = getConfig(config);
64957
+ const config = getConfig(userConfig);
64447
64958
  const diagnostics = [];
64448
64959
  const sys = config.sys;
64449
64960
  const compilerCtx = new CompilerContext();
@@ -65119,7 +65630,7 @@ const getComponentPathContent = (componentGraph, outputTarget) => {
65119
65630
  const dependencies = [
65120
65631
  {
65121
65632
  name: "@rindo/core",
65122
- version: "2.16.1",
65633
+ version: "2.17.1",
65123
65634
  main: "compiler/rindo.js",
65124
65635
  resources: [
65125
65636
  "package.json",
@@ -65291,11 +65802,11 @@ const getUserConfigName = (config, correctConfigName) => {
65291
65802
  };
65292
65803
 
65293
65804
  const validateDevServer = (config, diagnostics) => {
65294
- var _a, _b, _c, _d, _e, _f, _g;
65805
+ var _a, _b, _c, _d, _e;
65295
65806
  if ((config.devServer === null || config.devServer) === false) {
65296
65807
  return undefined;
65297
65808
  }
65298
- const flags = (_a = config.flags) !== null && _a !== void 0 ? _a : {};
65809
+ const { flags } = config;
65299
65810
  const devServer = { ...config.devServer };
65300
65811
  if (flags.address && isString$1(flags.address)) {
65301
65812
  devServer.address = flags.address;
@@ -65353,14 +65864,14 @@ const validateDevServer = (config, diagnostics) => {
65353
65864
  if (!isBoolean$1(devServer.websocket)) {
65354
65865
  devServer.websocket = true;
65355
65866
  }
65356
- if ((_b = config === null || config === void 0 ? void 0 : config.flags) === null || _b === void 0 ? void 0 : _b.ssr) {
65867
+ if (flags.ssr) {
65357
65868
  devServer.ssr = true;
65358
65869
  }
65359
65870
  else {
65360
65871
  devServer.ssr = !!devServer.ssr;
65361
65872
  }
65362
65873
  if (devServer.ssr) {
65363
- const wwwOutput = ((_c = config.outputTargets) !== null && _c !== void 0 ? _c : []).find(isOutputTargetWww);
65874
+ const wwwOutput = ((_a = config.outputTargets) !== null && _a !== void 0 ? _a : []).find(isOutputTargetWww);
65364
65875
  devServer.prerenderConfig = wwwOutput === null || wwwOutput === void 0 ? void 0 : wwwOutput.prerenderConfig;
65365
65876
  }
65366
65877
  if (isString$1(config.srcIndexHtml)) {
@@ -65386,15 +65897,15 @@ const validateDevServer = (config, diagnostics) => {
65386
65897
  }
65387
65898
  let serveDir;
65388
65899
  let basePath;
65389
- const wwwOutputTarget = ((_d = config.outputTargets) !== null && _d !== void 0 ? _d : []).find(isOutputTargetWww);
65900
+ const wwwOutputTarget = ((_b = config.outputTargets) !== null && _b !== void 0 ? _b : []).find(isOutputTargetWww);
65390
65901
  if (wwwOutputTarget) {
65391
- const baseUrl = new URL((_e = wwwOutputTarget.baseUrl) !== null && _e !== void 0 ? _e : '', 'http://config-rindojs.web.app');
65902
+ const baseUrl = new URL((_c = wwwOutputTarget.baseUrl) !== null && _c !== void 0 ? _c : '', 'http://config-rindojs.web.app');
65392
65903
  basePath = baseUrl.pathname;
65393
- serveDir = (_f = wwwOutputTarget.appDir) !== null && _f !== void 0 ? _f : '';
65904
+ serveDir = (_d = wwwOutputTarget.appDir) !== null && _d !== void 0 ? _d : '';
65394
65905
  }
65395
65906
  else {
65396
65907
  basePath = '';
65397
- serveDir = (_g = config.rootDir) !== null && _g !== void 0 ? _g : '';
65908
+ serveDir = (_e = config.rootDir) !== null && _e !== void 0 ? _e : '';
65398
65909
  }
65399
65910
  if (!isString$1(basePath) || basePath.trim() === '') {
65400
65911
  basePath = `/`;
@@ -65528,11 +66039,19 @@ const validateHydrated = (config) => {
65528
66039
  return hydratedFlag;
65529
66040
  };
65530
66041
 
66042
+ /**
66043
+ * Validate and return DIST_COLLECTION output targets, ensuring that the `dir`
66044
+ * property is set on them.
66045
+ *
66046
+ * @param config the user-supplied configuration object
66047
+ * @param userOutputs an array of output targets
66048
+ * @returns an array of validated DIST_COLLECTION output targets
66049
+ */
65531
66050
  const validateCollection = (config, userOutputs) => {
65532
- return userOutputs.filter(isOutputTargetDistCollection).map((o) => {
66051
+ return userOutputs.filter(isOutputTargetDistCollection).map((outputTarget) => {
65533
66052
  return {
65534
- ...o,
65535
- dir: getAbsolutePath(config, o.dir || 'dist/collection'),
66053
+ ...outputTarget,
66054
+ dir: getAbsolutePath(config, outputTarget.dir || 'dist/collection'),
65536
66055
  };
65537
66056
  });
65538
66057
  };
@@ -65866,7 +66385,7 @@ const validateHydrateScript = (config, userOutputs) => {
65866
66385
  // we don't already have a hydrate output target
65867
66386
  // let's still see if we require one because of other output targets
65868
66387
  const hasWwwOutput = userOutputs.filter(isOutputTargetWww).some((o) => isString$1(o.indexHtml));
65869
- const shouldBuildHydrate = (config === null || config === void 0 ? void 0 : config.flags.prerender) || (config === null || config === void 0 ? void 0 : config.flags.ssr);
66388
+ const shouldBuildHydrate = config.flags.prerender || config.flags.ssr;
65870
66389
  if (hasWwwOutput && shouldBuildHydrate) {
65871
66390
  // we're prerendering a www output target, so we'll need a hydrate app
65872
66391
  let hydrateDir;
@@ -65942,7 +66461,7 @@ const validateStats = (userConfig, userOutputs) => {
65942
66461
  };
65943
66462
 
65944
66463
  const validatePrerender = (config, diagnostics, outputTarget) => {
65945
- if (!config.flags || (!config.flags.ssr && !config.flags.prerender && config.flags.task !== 'prerender')) {
66464
+ if (!config.flags.ssr && !config.flags.prerender && config.flags.task !== 'prerender') {
65946
66465
  return;
65947
66466
  }
65948
66467
  outputTarget.baseUrl = normalizePath$1(outputTarget.baseUrl);
@@ -65967,8 +66486,6 @@ const validatePrerender = (config, diagnostics, outputTarget) => {
65967
66486
  }
65968
66487
  };
65969
66488
 
65970
- const HOST_CONFIG_FILENAME = 'host.config.json';
65971
-
65972
66489
  const validateServiceWorker = (config, outputTarget) => {
65973
66490
  if (outputTarget.serviceWorker === false) {
65974
66491
  return;
@@ -66021,14 +66538,15 @@ const validateServiceWorker = (config, outputTarget) => {
66021
66538
  }
66022
66539
  };
66023
66540
  const addGlobIgnores = (config, globIgnores) => {
66024
- globIgnores.push(`**/${HOST_CONFIG_FILENAME}`, `**/*.system.entry.js`, `**/*.system.js`, `**/${config.fsNamespace}.js`, `**/${config.fsNamespace}.esm.js`, `**/${config.fsNamespace}.css`);
66541
+ globIgnores.push(`**/host.config.json`, // the filename of the host configuration
66542
+ `**/*.system.entry.js`, `**/*.system.js`, `**/${config.fsNamespace}.js`, `**/${config.fsNamespace}.esm.js`, `**/${config.fsNamespace}.css`);
66025
66543
  };
66026
66544
  const DEFAULT_GLOB_PATTERNS = ['*.html', '**/*.{js,css,json}'];
66027
66545
  const DEFAULT_FILENAME = 'sw.js';
66028
66546
 
66029
66547
  const validateWww = (config, diagnostics, userOutputs) => {
66030
66548
  const hasOutputTargets = userOutputs.length > 0;
66031
- const hasE2eTests = !!(config.flags && config.flags.e2e);
66549
+ const hasE2eTests = !!config.flags.e2e;
66032
66550
  const userWwwOutputs = userOutputs.filter(isOutputTargetWww);
66033
66551
  if (!hasOutputTargets ||
66034
66552
  (hasE2eTests && !userOutputs.some(isOutputTargetWww) && !userOutputs.some(isOutputTargetDist))) {
@@ -66282,7 +66800,7 @@ const DEFAULT_ROLLUP_CONFIG = {
66282
66800
  const validateTesting = (config, diagnostics) => {
66283
66801
  var _a;
66284
66802
  const testing = (config.testing = Object.assign({}, config.testing || {}));
66285
- if (!config.flags || (!config.flags.e2e && !config.flags.spec)) {
66803
+ if (!config.flags.e2e && !config.flags.spec) {
66286
66804
  return;
66287
66805
  }
66288
66806
  let configPathDir = config.configPath;
@@ -66320,7 +66838,7 @@ const validateTesting = (config, diagnostics) => {
66320
66838
  else {
66321
66839
  testing.rootDir = config.rootDir;
66322
66840
  }
66323
- if (config.flags && typeof config.flags.screenshotConnector === 'string') {
66841
+ if (typeof config.flags.screenshotConnector === 'string') {
66324
66842
  testing.screenshotConnector = config.flags.screenshotConnector;
66325
66843
  }
66326
66844
  if (typeof testing.screenshotConnector === 'string') {
@@ -66442,13 +66960,11 @@ const validateWorkers = (config) => {
66442
66960
  if (typeof config.maxConcurrentWorkers !== 'number') {
66443
66961
  config.maxConcurrentWorkers = 8;
66444
66962
  }
66445
- if (config.flags) {
66446
- if (typeof config.flags.maxWorkers === 'number') {
66447
- config.maxConcurrentWorkers = config.flags.maxWorkers;
66448
- }
66449
- else if (config.flags.ci) {
66450
- config.maxConcurrentWorkers = 4;
66451
- }
66963
+ if (typeof config.flags.maxWorkers === 'number') {
66964
+ config.maxConcurrentWorkers = config.flags.maxWorkers;
66965
+ }
66966
+ else if (config.flags.ci) {
66967
+ config.maxConcurrentWorkers = 4;
66452
66968
  }
66453
66969
  config.maxConcurrentWorkers = Math.max(Math.min(config.maxConcurrentWorkers, 16), 0);
66454
66970
  if (config.devServer) {
@@ -66462,111 +66978,119 @@ const validateWorkers = (config) => {
66462
66978
  * `UnvalidatedConfig` to a `Config`.
66463
66979
  *
66464
66980
  * @param userConfig an unvalidated config that we've gotten from a user
66981
+ * @param bootstrapConfig the initial configuration provided by the user (or generated by Rindo) used to bootstrap
66982
+ * configuration loading and validation
66465
66983
  * @returns an object with config and diagnostics props
66466
66984
  */
66467
- const validateConfig = (userConfig = {}) => {
66985
+ const validateConfig = (userConfig = {}, bootstrapConfig) => {
66468
66986
  const config = Object.assign({}, userConfig || {}); // not positive it's json safe
66469
66987
  const diagnostics = [];
66470
- // copy flags (we know it'll be json safe)
66471
- config.flags = JSON.parse(JSON.stringify(config.flags || {}));
66988
+ const logger = bootstrapConfig.logger || config.logger || createLogger();
66989
+ const validatedConfig = {
66990
+ ...config,
66991
+ // flags _should_ be JSON safe
66992
+ flags: JSON.parse(JSON.stringify(config.flags || {})),
66993
+ logger,
66994
+ };
66472
66995
  // default devMode false
66473
- if (config.flags.prod) {
66474
- config.devMode = false;
66475
- }
66476
- else if (config.flags.dev) {
66477
- config.devMode = true;
66478
- }
66479
- else if (!isBoolean$1(config.devMode)) {
66480
- config.devMode = DEFAULT_DEV_MODE;
66481
- }
66482
- config.extras = config.extras || {};
66483
- config.extras.appendChildSlotFix = !!config.extras.appendChildSlotFix;
66484
- config.extras.cloneNodeFix = !!config.extras.cloneNodeFix;
66485
- config.extras.cssVarsShim = !!config.extras.cssVarsShim;
66486
- config.extras.dynamicImportShim = !!config.extras.dynamicImportShim;
66487
- config.extras.lifecycleDOMEvents = !!config.extras.lifecycleDOMEvents;
66488
- config.extras.safari10 = !!config.extras.safari10;
66489
- config.extras.scriptDataOpts = !!config.extras.scriptDataOpts;
66490
- config.extras.shadowDomShim = !!config.extras.shadowDomShim;
66491
- config.extras.slotChildNodesFix = !!config.extras.slotChildNodesFix;
66492
- config.extras.initializeNextTick = !!config.extras.initializeNextTick;
66493
- config.extras.tagNameTransform = !!config.extras.tagNameTransform;
66494
- config.buildEs5 = config.buildEs5 === true || (!config.devMode && config.buildEs5 === 'prod');
66495
- setBooleanConfig(config, 'minifyCss', null, !config.devMode);
66496
- setBooleanConfig(config, 'minifyJs', null, !config.devMode);
66497
- setBooleanConfig(config, 'sourceMap', null, typeof config.sourceMap === 'undefined' ? false : config.sourceMap);
66498
- setBooleanConfig(config, 'watch', 'watch', false);
66499
- setBooleanConfig(config, 'buildDocs', 'docs', !config.devMode);
66500
- setBooleanConfig(config, 'buildDist', 'esm', !config.devMode || config.buildEs5);
66501
- setBooleanConfig(config, 'profile', 'profile', config.devMode);
66502
- setBooleanConfig(config, 'writeLog', 'log', false);
66503
- setBooleanConfig(config, 'buildAppCore', null, true);
66504
- setBooleanConfig(config, 'autoprefixCss', null, config.buildEs5);
66505
- setBooleanConfig(config, 'validateTypes', null, !config._isTesting);
66506
- setBooleanConfig(config, 'allowInlineScripts', null, true);
66507
- if (!isString$1(config.taskQueue)) {
66508
- config.taskQueue = 'async';
66996
+ if (validatedConfig.flags.prod) {
66997
+ validatedConfig.devMode = false;
66998
+ }
66999
+ else if (validatedConfig.flags.dev) {
67000
+ validatedConfig.devMode = true;
67001
+ }
67002
+ else if (!isBoolean$1(validatedConfig.devMode)) {
67003
+ validatedConfig.devMode = DEFAULT_DEV_MODE;
67004
+ }
67005
+ validatedConfig.extras = validatedConfig.extras || {};
67006
+ validatedConfig.extras.appendChildSlotFix = !!validatedConfig.extras.appendChildSlotFix;
67007
+ validatedConfig.extras.cloneNodeFix = !!validatedConfig.extras.cloneNodeFix;
67008
+ validatedConfig.extras.cssVarsShim = !!validatedConfig.extras.cssVarsShim;
67009
+ validatedConfig.extras.dynamicImportShim = !!validatedConfig.extras.dynamicImportShim;
67010
+ validatedConfig.extras.lifecycleDOMEvents = !!validatedConfig.extras.lifecycleDOMEvents;
67011
+ validatedConfig.extras.safari10 = !!validatedConfig.extras.safari10;
67012
+ validatedConfig.extras.scriptDataOpts = !!validatedConfig.extras.scriptDataOpts;
67013
+ validatedConfig.extras.shadowDomShim = !!validatedConfig.extras.shadowDomShim;
67014
+ validatedConfig.extras.slotChildNodesFix = !!validatedConfig.extras.slotChildNodesFix;
67015
+ validatedConfig.extras.initializeNextTick = !!validatedConfig.extras.initializeNextTick;
67016
+ validatedConfig.extras.tagNameTransform = !!validatedConfig.extras.tagNameTransform;
67017
+ validatedConfig.buildEs5 =
67018
+ validatedConfig.buildEs5 === true || (!validatedConfig.devMode && validatedConfig.buildEs5 === 'prod');
67019
+ setBooleanConfig(validatedConfig, 'minifyCss', null, !validatedConfig.devMode);
67020
+ setBooleanConfig(validatedConfig, 'minifyJs', null, !validatedConfig.devMode);
67021
+ setBooleanConfig(validatedConfig, 'sourceMap', null, typeof validatedConfig.sourceMap === 'undefined' ? false : validatedConfig.sourceMap);
67022
+ setBooleanConfig(validatedConfig, 'watch', 'watch', false);
67023
+ setBooleanConfig(validatedConfig, 'buildDocs', 'docs', !validatedConfig.devMode);
67024
+ setBooleanConfig(validatedConfig, 'buildDist', 'esm', !validatedConfig.devMode || validatedConfig.buildEs5);
67025
+ setBooleanConfig(validatedConfig, 'profile', 'profile', validatedConfig.devMode);
67026
+ setBooleanConfig(validatedConfig, 'writeLog', 'log', false);
67027
+ setBooleanConfig(validatedConfig, 'buildAppCore', null, true);
67028
+ setBooleanConfig(validatedConfig, 'autoprefixCss', null, validatedConfig.buildEs5);
67029
+ setBooleanConfig(validatedConfig, 'validateTypes', null, !validatedConfig._isTesting);
67030
+ setBooleanConfig(validatedConfig, 'allowInlineScripts', null, true);
67031
+ if (!isString$1(validatedConfig.taskQueue)) {
67032
+ validatedConfig.taskQueue = 'async';
66509
67033
  }
66510
67034
  // hash file names
66511
- if (!isBoolean$1(config.hashFileNames)) {
66512
- config.hashFileNames = !config.devMode;
67035
+ if (!isBoolean$1(validatedConfig.hashFileNames)) {
67036
+ validatedConfig.hashFileNames = !validatedConfig.devMode;
66513
67037
  }
66514
- if (!isNumber$1(config.hashedFileNameLength)) {
66515
- config.hashedFileNameLength = DEFAULT_HASHED_FILENAME_LENTH;
67038
+ if (!isNumber$1(validatedConfig.hashedFileNameLength)) {
67039
+ validatedConfig.hashedFileNameLength = DEFAULT_HASHED_FILENAME_LENTH;
66516
67040
  }
66517
- if (config.hashedFileNameLength < MIN_HASHED_FILENAME_LENTH) {
67041
+ if (validatedConfig.hashedFileNameLength < MIN_HASHED_FILENAME_LENTH) {
66518
67042
  const err = buildError(diagnostics);
66519
- err.messageText = `config.hashedFileNameLength must be at least ${MIN_HASHED_FILENAME_LENTH} characters`;
67043
+ err.messageText = `validatedConfig.hashedFileNameLength must be at least ${MIN_HASHED_FILENAME_LENTH} characters`;
66520
67044
  }
66521
- if (config.hashedFileNameLength > MAX_HASHED_FILENAME_LENTH) {
67045
+ if (validatedConfig.hashedFileNameLength > MAX_HASHED_FILENAME_LENTH) {
66522
67046
  const err = buildError(diagnostics);
66523
- err.messageText = `config.hashedFileNameLength cannot be more than ${MAX_HASHED_FILENAME_LENTH} characters`;
67047
+ err.messageText = `validatedConfig.hashedFileNameLength cannot be more than ${MAX_HASHED_FILENAME_LENTH} characters`;
66524
67048
  }
66525
- if (!config.env) {
66526
- config.env = {};
67049
+ if (!validatedConfig.env) {
67050
+ validatedConfig.env = {};
66527
67051
  }
66528
67052
  // get a good namespace
66529
- validateNamespace(config, diagnostics);
67053
+ validateNamespace(validatedConfig, diagnostics);
66530
67054
  // figure out all of the config paths and absolute paths
66531
- validatePaths(config);
67055
+ validatePaths(validatedConfig);
66532
67056
  // outputTargets
66533
- validateOutputTargets(config, diagnostics);
67057
+ validateOutputTargets(validatedConfig, diagnostics);
66534
67058
  // plugins
66535
- validatePlugins(config, diagnostics);
67059
+ validatePlugins(validatedConfig, diagnostics);
66536
67060
  // rollup config
66537
- validateRollupConfig(config);
67061
+ validateRollupConfig(validatedConfig);
66538
67062
  // dev server
66539
- config.devServer = validateDevServer(config, diagnostics);
67063
+ validatedConfig.devServer = validateDevServer(validatedConfig, diagnostics);
66540
67064
  // testing
66541
- validateTesting(config, diagnostics);
67065
+ validateTesting(validatedConfig, diagnostics);
66542
67066
  // hydrate flag
66543
- config.hydratedFlag = validateHydrated(config);
67067
+ validatedConfig.hydratedFlag = validateHydrated(validatedConfig);
66544
67068
  // bundles
66545
- if (Array.isArray(config.bundles)) {
66546
- config.bundles = sortBy(config.bundles, (a) => a.components.length);
67069
+ if (Array.isArray(validatedConfig.bundles)) {
67070
+ validatedConfig.bundles = sortBy(validatedConfig.bundles, (a) => a.components.length);
66547
67071
  }
66548
67072
  else {
66549
- config.bundles = [];
67073
+ validatedConfig.bundles = [];
66550
67074
  }
66551
67075
  // validate how many workers we can use
66552
- validateWorkers(config);
67076
+ validateWorkers(validatedConfig);
66553
67077
  // default devInspector to whatever devMode is
66554
- setBooleanConfig(config, 'devInspector', null, config.devMode);
66555
- if (!config._isTesting) {
66556
- validateDistNamespace(config, diagnostics);
67078
+ setBooleanConfig(validatedConfig, 'devInspector', null, validatedConfig.devMode);
67079
+ if (!validatedConfig._isTesting) {
67080
+ validateDistNamespace(validatedConfig, diagnostics);
66557
67081
  }
66558
- setBooleanConfig(config, 'enableCache', 'cache', true);
66559
- if (!Array.isArray(config.watchIgnoredRegex) && config.watchIgnoredRegex != null) {
66560
- config.watchIgnoredRegex = [config.watchIgnoredRegex];
67082
+ setBooleanConfig(validatedConfig, 'enableCache', 'cache', true);
67083
+ if (!Array.isArray(validatedConfig.watchIgnoredRegex) && validatedConfig.watchIgnoredRegex != null) {
67084
+ validatedConfig.watchIgnoredRegex = [validatedConfig.watchIgnoredRegex];
66561
67085
  }
66562
- config.watchIgnoredRegex = (config.watchIgnoredRegex || []).reduce((arr, reg) => {
67086
+ validatedConfig.watchIgnoredRegex = (validatedConfig.watchIgnoredRegex || []).reduce((arr, reg) => {
66563
67087
  if (reg instanceof RegExp) {
66564
67088
  arr.push(reg);
66565
67089
  }
66566
67090
  return arr;
66567
67091
  }, []);
66568
67092
  return {
66569
- config,
67093
+ config: validatedConfig,
66570
67094
  diagnostics,
66571
67095
  };
66572
67096
  };
@@ -66717,6 +67241,21 @@ const createDefaultTsConfig = (config) => JSON.stringify({
66717
67241
  const hasSrcDirectoryInclude = (includeProp, src) => Array.isArray(includeProp) && includeProp.includes(src);
66718
67242
  const hasRindoConfigInclude = (includeProp) => Array.isArray(includeProp) && includeProp.includes('rindo.config.ts');
66719
67243
 
67244
+ /**
67245
+ * Load and validate a configuration to use throughout the lifetime of any Rindo task (build, test, etc.).
67246
+ *
67247
+ * Users can provide configurations multiple ways simultaneously:
67248
+ * - as an object of the `init` argument to this function
67249
+ * - through a path to a configuration file that exists on disk
67250
+ *
67251
+ * In the case of both being present, the two configurations will be merged. The fields of the former will take precedence
67252
+ * over the fields of the latter.
67253
+ *
67254
+ * @param init the initial configuration provided by the user (or generated by Rindo) used to bootstrap configuration
67255
+ * loading and validation
67256
+ * @returns the results of loading a configuration
67257
+ * @public
67258
+ */
66720
67259
  const loadConfig = async (init = {}) => {
66721
67260
  const results = {
66722
67261
  config: null,
@@ -66730,6 +67269,7 @@ const loadConfig = async (init = {}) => {
66730
67269
  extends: null,
66731
67270
  },
66732
67271
  };
67272
+ const unknownConfig = {};
66733
67273
  try {
66734
67274
  const sys = init.sys || createSystem();
66735
67275
  const config = init.config || {};
@@ -66738,22 +67278,22 @@ const loadConfig = async (init = {}) => {
66738
67278
  if (hasError(results.diagnostics)) {
66739
67279
  return results;
66740
67280
  }
66741
- if (loadedConfigFile != null) {
67281
+ if (loadedConfigFile !== null) {
66742
67282
  // merge the user's config object into their loaded config file
66743
67283
  configPath = loadedConfigFile.configPath;
66744
- results.config = { ...loadedConfigFile, ...config };
66745
- results.config.configPath = configPath;
66746
- results.config.rootDir = normalizePath$1(dirname(configPath));
67284
+ unknownConfig.config = { ...loadedConfigFile, ...config };
67285
+ unknownConfig.config.configPath = configPath;
67286
+ unknownConfig.config.rootDir = normalizePath$1(dirname(configPath));
66747
67287
  }
66748
67288
  else {
66749
67289
  // no rindo.config.ts or .js file, which is fine
66750
67290
  // #0CJS ¯\_(ツ)_/¯
66751
- results.config = { ...config };
66752
- results.config.configPath = null;
66753
- results.config.rootDir = normalizePath$1(sys.getCurrentDirectory());
67291
+ unknownConfig.config = { ...config };
67292
+ unknownConfig.config.configPath = null;
67293
+ unknownConfig.config.rootDir = normalizePath$1(sys.getCurrentDirectory());
66754
67294
  }
66755
- results.config.sys = sys;
66756
- const validated = validateConfig(results.config);
67295
+ unknownConfig.config.sys = sys;
67296
+ const validated = validateConfig(unknownConfig.config, init);
66757
67297
  results.diagnostics.push(...validated.diagnostics);
66758
67298
  if (hasError(results.diagnostics)) {
66759
67299
  return results;
@@ -66768,7 +67308,6 @@ const loadConfig = async (init = {}) => {
66768
67308
  else if (typeof results.config.logLevel !== 'string') {
66769
67309
  results.config.logLevel = 'info';
66770
67310
  }
66771
- results.config.logger = init.logger || results.config.logger || createLogger();
66772
67311
  results.config.logger.setLevel(results.config.logLevel);
66773
67312
  if (!hasError(results.diagnostics)) {
66774
67313
  const tsConfigResults = await validateTsConfig(results.config, sys, init);
@@ -66788,6 +67327,15 @@ const loadConfig = async (init = {}) => {
66788
67327
  }
66789
67328
  return results;
66790
67329
  };
67330
+ /**
67331
+ * Load a Rindo configuration file from disk
67332
+ * @param sys the underlying System entity to use to interact with the operating system
67333
+ * @param diagnostics a series of diagnostics used to track errors & warnings throughout the loading process. Entries
67334
+ * may be added to this list in the event of an error.
67335
+ * @param configPath the path to the configuration file to load
67336
+ * @returns an unvalidated configuration. In the event of an error, additional diagnostics may be pushed to the
67337
+ * provided `diagnostics` argument and `null` will be returned.
67338
+ */
66791
67339
  const loadConfigFile = async (sys, diagnostics, configPath) => {
66792
67340
  let config = null;
66793
67341
  if (isString$1(configPath)) {
@@ -66807,6 +67355,15 @@ const loadConfigFile = async (sys, diagnostics, configPath) => {
66807
67355
  }
66808
67356
  return config;
66809
67357
  };
67358
+ /**
67359
+ * Load the configuration file, based on the environment that Rindo is being run in
67360
+ * @param sys the underlying System entity to use to interact with the operating system
67361
+ * @param diagnostics a series of diagnostics used to track errors & warnings throughout the loading process. Entries
67362
+ * may be added to this list in the event of an error.
67363
+ * @param configFilePath the path to the configuration file to load
67364
+ * @returns an unvalidated configuration. In the event of an error, additional diagnostics may be pushed to the
67365
+ * provided `diagnostics` argument and `null` will be returned.
67366
+ */
66810
67367
  const evaluateConfigFile = async (sys, diagnostics, configFilePath) => {
66811
67368
  let configFileData = null;
66812
67369
  try {
@@ -66831,6 +67388,16 @@ const evaluateConfigFile = async (sys, diagnostics, configFilePath) => {
66831
67388
  }
66832
67389
  return configFileData;
66833
67390
  };
67391
+ /**
67392
+ * Transpiles the provided TypeScript source text into JavaScript.
67393
+ *
67394
+ * This function is intended to be used on a `rindo.config.ts` file
67395
+ *
67396
+ * @param diagnostics a collection of compiler diagnostics to check as a part of the compilation process
67397
+ * @param sourceText the text to transpile
67398
+ * @param filePath the name of the file to transpile
67399
+ * @returns the transpiled text. If there are any diagnostics in the provided collection, the provided source is returned
67400
+ */
66834
67401
  const transpileTypedConfig = (diagnostics, sourceText, filePath) => {
66835
67402
  // let's transpile an awesome rindo.config.ts file into
66836
67403
  // a boring rindo.config.js file