@jsenv/core 30.4.1 → 31.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -9,9 +9,9 @@ import os, { networkInterfaces } from "node:os";
9
9
  import tty from "node:tty";
10
10
  import stringWidth from "string-width";
11
11
  import net, { createServer, isIP } from "node:net";
12
- import http from "node:http";
13
12
  import cluster from "node:cluster";
14
13
  import { performance as performance$1 } from "node:perf_hooks";
14
+ import http from "node:http";
15
15
  import { Readable, Stream, Writable } from "node:stream";
16
16
  import { Http2ServerResponse } from "node:http2";
17
17
  import { lookup } from "node:dns";
@@ -592,7 +592,7 @@ const urlToFileSystemPath = url => {
592
592
  return fileSystemPath;
593
593
  };
594
594
 
595
- const assertAndNormalizeDirectoryUrl = value => {
595
+ const validateDirectoryUrl = value => {
596
596
  let urlString;
597
597
  if (value instanceof URL) {
598
598
  urlString = value.href;
@@ -603,19 +603,45 @@ const assertAndNormalizeDirectoryUrl = value => {
603
603
  try {
604
604
  urlString = String(new URL(value));
605
605
  } catch (e) {
606
- throw new TypeError(`directoryUrl must be a valid url, received ${value}`);
606
+ return {
607
+ valid: false,
608
+ value,
609
+ message: `must be a valid url`
610
+ };
607
611
  }
608
612
  }
609
613
  } else {
610
- throw new TypeError(`directoryUrl must be a string or an url, received ${value}`);
614
+ return {
615
+ valid: false,
616
+ value,
617
+ message: `must be a string or an url`
618
+ };
611
619
  }
612
620
  if (!urlString.startsWith("file://")) {
613
- throw new Error(`directoryUrl must starts with file://, received ${value}`);
621
+ return {
622
+ valid: false,
623
+ value,
624
+ message: 'must start with "file://"'
625
+ };
614
626
  }
615
- return ensurePathnameTrailingSlash(urlString);
627
+ return {
628
+ valid: true,
629
+ value: ensurePathnameTrailingSlash(urlString)
630
+ };
631
+ };
632
+ const assertAndNormalizeDirectoryUrl = directoryUrl => {
633
+ const {
634
+ valid,
635
+ message,
636
+ value
637
+ } = validateDirectoryUrl(directoryUrl);
638
+ if (!valid) {
639
+ throw new TypeError(`directoryUrl ${message}, got ${value}`);
640
+ }
641
+ return value;
616
642
  };
617
643
 
618
- const assertAndNormalizeFileUrl = (value, baseUrl) => {
644
+ const validateFileUrl = (value, baseUrl) => {
619
645
  let urlString;
620
646
  if (value instanceof URL) {
621
647
  urlString = value.href;
@@ -626,16 +652,42 @@ const assertAndNormalizeFileUrl = (value, baseUrl) => {
626
652
  try {
627
653
  urlString = String(new URL(value, baseUrl));
628
654
  } catch (e) {
629
- throw new TypeError(`fileUrl must be a valid url, received ${value}`);
655
+ return {
656
+ valid: false,
657
+ value,
658
+ message: "must be a valid url"
659
+ };
630
660
  }
631
661
  }
632
662
  } else {
633
- throw new TypeError(`fileUrl must be a string or an url, received ${value}`);
663
+ return {
664
+ valid: false,
665
+ value,
666
+ message: "must be a string or an url"
667
+ };
634
668
  }
635
669
  if (!urlString.startsWith("file://")) {
636
- throw new Error(`fileUrl must starts with file://, received ${value}`);
670
+ return {
671
+ valid: false,
672
+ value,
673
+ message: 'must start with "file://"'
674
+ };
637
675
  }
638
- return urlString;
676
+ return {
677
+ valid: true,
678
+ value: urlString
679
+ };
680
+ };
681
+ const assertAndNormalizeFileUrl = (fileUrl, baseUrl) => {
682
+ const {
683
+ valid,
684
+ message,
685
+ value
686
+ } = validateFileUrl(fileUrl, baseUrl);
687
+ if (!valid) {
688
+ throw new TypeError(`fileUrl ${message}, got ${fileUrl}`);
689
+ }
690
+ return value;
639
691
  };
640
692
 
641
693
  const statsToType = stats => {
@@ -753,7 +805,7 @@ const getPermissionOrComputeDefault = (action, subject, permissions) => {
753
805
  * - stats object documentation on Node.js
754
806
  * https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_class_fs_stats
755
807
  */
756
- const isWindows$2 = process.platform === "win32";
808
+ const isWindows$3 = process.platform === "win32";
757
809
  const readEntryStat = async (source, {
758
810
  nullIfNotFound = false,
759
811
  followLink = true
@@ -767,7 +819,7 @@ const readEntryStat = async (source, {
767
819
  return readStat(sourcePath, {
768
820
  followLink,
769
821
  ...handleNotFoundOption,
770
- ...(isWindows$2 ? {
822
+ ...(isWindows$3 ? {
771
823
  // Windows can EPERM on stat
772
824
  handlePermissionDeniedError: async error => {
773
825
  console.error(`trying to fix windows EPERM after stats on ${sourcePath}`);
@@ -1715,7 +1767,7 @@ const ensureParentDirectories = async destination => {
1715
1767
  });
1716
1768
  };
1717
1769
 
1718
- const isWindows$1 = process.platform === "win32";
1770
+ const isWindows$2 = process.platform === "win32";
1719
1771
  const baseUrlFallback = fileSystemPathToUrl$1(process.cwd());
1720
1772
 
1721
1773
  /**
@@ -1737,7 +1789,7 @@ const ensureWindowsDriveLetter = (url, baseUrl) => {
1737
1789
  } catch (e) {
1738
1790
  throw new Error(`absolute url expected but got ${url}`);
1739
1791
  }
1740
- if (!isWindows$1) {
1792
+ if (!isWindows$2) {
1741
1793
  return url;
1742
1794
  }
1743
1795
  try {
@@ -1834,10 +1886,10 @@ const guardTooFastSecondCallPerFile = (callback, cooldownBetweenFileEvents = 40)
1834
1886
  };
1835
1887
  };
1836
1888
 
1837
- const isWindows = process.platform === "win32";
1889
+ const isWindows$1 = process.platform === "win32";
1838
1890
  const createWatcher = (sourcePath, options) => {
1839
1891
  const watcher = watch(sourcePath, options);
1840
- if (isWindows) {
1892
+ if (isWindows$1) {
1841
1893
  watcher.on("error", async error => {
1842
1894
  // https://github.com/joyent/node/issues/4337
1843
1895
  if (error.code === "EPERM") {
@@ -2856,7 +2908,14 @@ const ESC = '\u001B[';
2856
2908
  const OSC = '\u001B]';
2857
2909
  const BEL = '\u0007';
2858
2910
  const SEP = ';';
2859
- const isTerminalApp = process$1.env.TERM_PROGRAM === 'Apple_Terminal';
2911
+
2912
+ /* global window */
2913
+ const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
2914
+ const isTerminalApp = !isBrowser && process$1.env.TERM_PROGRAM === 'Apple_Terminal';
2915
+ const isWindows = !isBrowser && process$1.platform === 'win32';
2916
+ const cwdFunction = isBrowser ? () => {
2917
+ throw new Error('`process.cwd()` only works in Node.js, not the browser.');
2918
+ } : process$1.cwd;
2860
2919
  const ansiEscapes = {};
2861
2920
  ansiEscapes.cursorTo = (x, y) => {
2862
2921
  if (typeof x !== 'number') {
@@ -2915,7 +2974,7 @@ ansiEscapes.eraseScreen = ESC + '2J';
2915
2974
  ansiEscapes.scrollUp = ESC + 'S';
2916
2975
  ansiEscapes.scrollDown = ESC + 'T';
2917
2976
  ansiEscapes.clearScreen = '\u001Bc';
2918
- ansiEscapes.clearTerminal = process$1.platform === 'win32' ? `${ansiEscapes.eraseScreen}${ESC}0f`
2977
+ ansiEscapes.clearTerminal = isWindows ? `${ansiEscapes.eraseScreen}${ESC}0f`
2919
2978
  // 1. Erases the screen (Only done in case `2` is not supported)
2920
2979
  // 2. Erases the whole screen including scrollback buffer
2921
2980
  // 3. Moves cursor to the top-left position
@@ -2937,7 +2996,7 @@ ansiEscapes.image = (buffer, options = {}) => {
2937
2996
  return returnValue + ':' + buffer.toString('base64') + BEL;
2938
2997
  };
2939
2998
  ansiEscapes.iTerm = {
2940
- setCwd: (cwd = process$1.cwd()) => `${OSC}50;CurrentDir=${cwd}${BEL}`,
2999
+ setCwd: (cwd = cwdFunction()) => `${OSC}50;CurrentDir=${cwd}${BEL}`,
2941
3000
  annotation(message, options = {}) {
2942
3001
  let returnValue = `${OSC}1337;`;
2943
3002
  const hasX = typeof options.x !== 'undefined';
@@ -4885,7 +4944,7 @@ const startServer = async ({
4885
4944
  logLevel,
4886
4945
  startLog = true,
4887
4946
  serverName = "server",
4888
- protocol = "http",
4947
+ https = false,
4889
4948
  http2 = false,
4890
4949
  http1Allowed = true,
4891
4950
  redirectHttpToHttps,
@@ -4896,8 +4955,6 @@ const startServer = async ({
4896
4955
  port = 0,
4897
4956
  // assign a random available port
4898
4957
  portHint,
4899
- privateKey,
4900
- certificate,
4901
4958
  // when inside a worker, we should not try to stop server on SIGINT
4902
4959
  // otherwise it can create an EPIPE error while primary process tries
4903
4960
  // to kill the server
@@ -4928,39 +4985,52 @@ const startServer = async ({
4928
4985
  // time allocated to server code to start reading the request body
4929
4986
  // after this delay the underlying stream is destroyed, attempting to read it would throw
4930
4987
  // if used the stream stays opened, it's only if the stream is not read at all that it gets destroyed
4931
- requestBodyLifetime = 60_000 * 2 // 2s
4988
+ requestBodyLifetime = 60_000 * 2,
4989
+ // 2s
4990
+ ...rest
4932
4991
  } = {}) => {
4992
+ // param validations
4993
+ {
4994
+ const unexpectedParamNames = Object.keys(rest);
4995
+ if (unexpectedParamNames.length > 0) {
4996
+ throw new TypeError(`${unexpectedParamNames.join(",")}: there is no such param`);
4997
+ }
4998
+ if (https) {
4999
+ if (typeof https !== "object") {
5000
+ throw new TypeError(`https must be an object, got ${https}`);
5001
+ }
5002
+ const {
5003
+ certificate,
5004
+ privateKey
5005
+ } = https;
5006
+ if (!certificate || !privateKey) {
5007
+ throw new TypeError(`https must be an object with { certificate, privateKey }`);
5008
+ }
5009
+ }
5010
+ if (http2 && !https) {
5011
+ throw new Error(`http2 needs https`);
5012
+ }
5013
+ }
4933
5014
  const logger = createLogger({
4934
5015
  logLevel
4935
5016
  });
4936
- if (protocol !== "http" && protocol !== "https") {
4937
- throw new Error(`protocol must be http or https, got ${protocol}`);
4938
- }
4939
- if (protocol === "https") {
4940
- if (!certificate) {
4941
- throw new Error(`missing certificate for https server`);
5017
+ // param warnings and normalization
5018
+ {
5019
+ if (redirectHttpToHttps === undefined && https && !allowHttpRequestOnHttps) {
5020
+ redirectHttpToHttps = true;
4942
5021
  }
4943
- if (!privateKey) {
4944
- throw new Error(`missing privateKey for https server`);
5022
+ if (redirectHttpToHttps && !https) {
5023
+ logger.warn(`redirectHttpToHttps ignored because protocol is http`);
5024
+ redirectHttpToHttps = false;
5025
+ }
5026
+ if (allowHttpRequestOnHttps && redirectHttpToHttps) {
5027
+ logger.warn(`redirectHttpToHttps ignored because allowHttpRequestOnHttps is enabled`);
5028
+ redirectHttpToHttps = false;
5029
+ }
5030
+ if (allowHttpRequestOnHttps && !https) {
5031
+ logger.warn(`allowHttpRequestOnHttps ignored because protocol is http`);
5032
+ allowHttpRequestOnHttps = false;
4945
5033
  }
4946
- }
4947
- if (http2 && protocol !== "https") {
4948
- throw new Error(`http2 needs "https" but protocol is "${protocol}"`);
4949
- }
4950
- if (redirectHttpToHttps === undefined && protocol === "https" && !allowHttpRequestOnHttps) {
4951
- redirectHttpToHttps = true;
4952
- }
4953
- if (redirectHttpToHttps && protocol === "http") {
4954
- logger.warn(`redirectHttpToHttps ignored because protocol is http`);
4955
- redirectHttpToHttps = false;
4956
- }
4957
- if (allowHttpRequestOnHttps && redirectHttpToHttps) {
4958
- logger.warn(`redirectHttpToHttps ignored because allowHttpRequestOnHttps is enabled`);
4959
- redirectHttpToHttps = false;
4960
- }
4961
- if (allowHttpRequestOnHttps && protocol === "http") {
4962
- logger.warn(`allowHttpRequestOnHttps ignored because protocol is http`);
4963
- allowHttpRequestOnHttps = false;
4964
5034
  }
4965
5035
  const server = {};
4966
5036
  const serviceController = createServiceController(services);
@@ -4991,11 +5061,9 @@ const startServer = async ({
4991
5061
  });
4992
5062
  startServerOperation.throwIfAborted();
4993
5063
  nodeServer = await createNodeServer({
4994
- protocol,
5064
+ https,
4995
5065
  redirectHttpToHttps,
4996
5066
  allowHttpRequestOnHttps,
4997
- certificate,
4998
- privateKey,
4999
5067
  http2,
5000
5068
  http1Allowed
5001
5069
  });
@@ -5006,6 +5074,7 @@ const startServer = async ({
5006
5074
  nodeServer.unref();
5007
5075
  }
5008
5076
  const createOrigin = hostname => {
5077
+ const protocol = https ? "https" : "http";
5009
5078
  if (isIP(hostname) === 6) {
5010
5079
  return `${protocol}://[${hostname}]`;
5011
5080
  }
@@ -5720,7 +5789,7 @@ const startServer = async ({
5720
5789
  let websocketServer = new WebSocketServer({
5721
5790
  noServer: true
5722
5791
  });
5723
- const websocketOrigin = protocol === "https" ? `wss://${hostname}:${port}` : `ws://${hostname}:${port}`;
5792
+ const websocketOrigin = https ? `wss://${hostname}:${port}` : `ws://${hostname}:${port}`;
5724
5793
  server.websocketOrigin = websocketOrigin;
5725
5794
  const upgradeCallback = (nodeRequest, socket, head) => {
5726
5795
  websocketServer.handleUpgrade(nodeRequest, socket, head, async websocket => {
@@ -5779,32 +5848,37 @@ const startServer = async ({
5779
5848
  return server;
5780
5849
  };
5781
5850
  const createNodeServer = async ({
5782
- protocol,
5851
+ https,
5783
5852
  redirectHttpToHttps,
5784
5853
  allowHttpRequestOnHttps,
5785
- certificate,
5786
- privateKey,
5787
5854
  http2,
5788
5855
  http1Allowed
5789
5856
  }) => {
5790
- if (protocol === "http") {
5791
- return http.createServer();
5792
- }
5793
- if (redirectHttpToHttps || allowHttpRequestOnHttps) {
5794
- return createPolyglotServer({
5857
+ if (https) {
5858
+ const {
5795
5859
  certificate,
5796
- privateKey,
5797
- http2,
5798
- http1Allowed
5860
+ privateKey
5861
+ } = https;
5862
+ if (redirectHttpToHttps || allowHttpRequestOnHttps) {
5863
+ return createPolyglotServer({
5864
+ certificate,
5865
+ privateKey,
5866
+ http2,
5867
+ http1Allowed
5868
+ });
5869
+ }
5870
+ const {
5871
+ createServer
5872
+ } = await import("node:https");
5873
+ return createServer({
5874
+ cert: certificate,
5875
+ key: privateKey
5799
5876
  });
5800
5877
  }
5801
5878
  const {
5802
5879
  createServer
5803
- } = await import("node:https");
5804
- return createServer({
5805
- cert: certificate,
5806
- key: privateKey
5807
- });
5880
+ } = await import("node:http");
5881
+ return createServer();
5808
5882
  };
5809
5883
  const testCanPushStream = http2Stream => {
5810
5884
  if (!http2Stream.pushAllowed) {
@@ -15038,10 +15112,7 @@ const jsenvPluginAsJsClassicLibrary = ({
15038
15112
  ...context,
15039
15113
  buildDirectoryUrl: context.outDirectoryUrl
15040
15114
  },
15041
- options: {
15042
- babelHelpersChunk: false,
15043
- preserveDynamicImport: true
15044
- }
15115
+ preserveDynamicImport: true
15045
15116
  });
15046
15117
  const jsModuleBundledUrlInfo = bundleUrlInfos[jsModuleUrlInfo.url];
15047
15118
  if (context.dev) {
@@ -20657,8 +20728,26 @@ const build = async ({
20657
20728
  writeOnFileSystem = true,
20658
20729
  writeGeneratedFiles = false,
20659
20730
  assetManifest = versioningMethod === "filename",
20660
- assetManifestFileRelativeUrl = "asset-manifest.json"
20731
+ assetManifestFileRelativeUrl = "asset-manifest.json",
20732
+ ...rest
20661
20733
  }) => {
20734
+ // param validation
20735
+ {
20736
+ const unexpectedParamNames = Object.keys(rest);
20737
+ if (unexpectedParamNames.length > 0) {
20738
+ throw new TypeError(`${unexpectedParamNames.join(",")}: there is no such param`);
20739
+ }
20740
+ const rootDirectoryUrlValidation = validateDirectoryUrl(rootDirectoryUrl);
20741
+ if (!rootDirectoryUrlValidation.valid) {
20742
+ throw new TypeError(`rootDirectoryUrl ${rootDirectoryUrlValidation.message}, got ${rootDirectoryUrl}`);
20743
+ }
20744
+ rootDirectoryUrl = rootDirectoryUrlValidation.value;
20745
+ const buildDirectoryUrlValidation = validateDirectoryUrl(buildDirectoryUrl);
20746
+ if (!buildDirectoryUrlValidation.valid) {
20747
+ throw new TypeError(`buildDirectoryUrl ${buildDirectoryUrlValidation.message}, got ${buildDirectoryUrlValidation}`);
20748
+ }
20749
+ buildDirectoryUrl = buildDirectoryUrlValidation.value;
20750
+ }
20662
20751
  const operation = Abort.startOperation();
20663
20752
  operation.addAbortSignal(signal);
20664
20753
  if (handleSIGINT) {
@@ -20668,8 +20757,6 @@ const build = async ({
20668
20757
  }, abort);
20669
20758
  });
20670
20759
  }
20671
- rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl);
20672
- buildDirectoryUrl = assertAndNormalizeDirectoryUrl(buildDirectoryUrl);
20673
20760
  assertEntryPoints({
20674
20761
  entryPoints
20675
20762
  });
@@ -22617,12 +22704,10 @@ const startDevServer = async ({
22617
22704
  handleSIGINT = true,
22618
22705
  logLevel = "info",
22619
22706
  serverLogLevel = "warn",
22620
- protocol = "http",
22707
+ https,
22621
22708
  // it's better to use http1 by default because it allows to get statusText in devtools
22622
22709
  // which gives valuable information when there is errors
22623
22710
  http2 = false,
22624
- certificate,
22625
- privateKey,
22626
22711
  hostname,
22627
22712
  port = 3456,
22628
22713
  acceptAnyIp,
@@ -22665,12 +22750,24 @@ const startDevServer = async ({
22665
22750
  sourcemapsSourcesContent,
22666
22751
  // no real need to write files during github workflow
22667
22752
  // and mitigates https://github.com/actions/runner-images/issues/3885
22668
- writeGeneratedFiles = !process.env.CI
22753
+ writeGeneratedFiles = !process.env.CI,
22754
+ ...rest
22669
22755
  }) => {
22756
+ // params type checking
22757
+ {
22758
+ const unexpectedParamNames = Object.keys(rest);
22759
+ if (unexpectedParamNames.length > 0) {
22760
+ throw new TypeError(`${unexpectedParamNames.join(",")}: there is no such param`);
22761
+ }
22762
+ const rootDirectoryUrlValidation = validateDirectoryUrl(rootDirectoryUrl);
22763
+ if (!rootDirectoryUrlValidation.valid) {
22764
+ throw new TypeError(`rootDirectoryUrl ${rootDirectoryUrlValidation.message}, got ${rootDirectoryUrl}`);
22765
+ }
22766
+ rootDirectoryUrl = rootDirectoryUrlValidation.value;
22767
+ }
22670
22768
  const logger = createLogger({
22671
22769
  logLevel
22672
22770
  });
22673
- rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl);
22674
22771
  const operation = Abort.startOperation();
22675
22772
  operation.addAbortSignal(signal);
22676
22773
  if (handleSIGINT) {
@@ -22760,10 +22857,8 @@ const startDevServer = async ({
22760
22857
  keepProcessAlive,
22761
22858
  logLevel: serverLogLevel,
22762
22859
  startLog: false,
22763
- protocol,
22860
+ https,
22764
22861
  http2,
22765
- certificate,
22766
- privateKey,
22767
22862
  acceptAnyIp,
22768
22863
  hostname,
22769
22864
  port,
@@ -22846,14 +22941,14 @@ const startDevServer = async ({
22846
22941
  // default error handling
22847
22942
  jsenvServiceErrorHandler({
22848
22943
  sendErrorDetails: true
22849
- })],
22850
- onStop: reason => {
22851
- onStop();
22852
- serverStopCallbacks.forEach(serverStopCallback => {
22853
- serverStopCallback(reason);
22854
- });
22855
- serverStopCallbacks.length = 0;
22856
- }
22944
+ })]
22945
+ });
22946
+ server.stoppedPromise.then(reason => {
22947
+ onStop();
22948
+ serverStopCallbacks.forEach(serverStopCallback => {
22949
+ serverStopCallback(reason);
22950
+ });
22951
+ serverStopCallbacks.length = 0;
22857
22952
  });
22858
22953
  startDevServerTask.done();
22859
22954
  if (hostname) {
@@ -23545,7 +23640,7 @@ const run = async ({
23545
23640
  cb(runResult);
23546
23641
  } catch (e) {
23547
23642
  cb({
23548
- status: "errored",
23643
+ status: "failed",
23549
23644
  errors: [e]
23550
23645
  });
23551
23646
  }
@@ -23576,7 +23671,7 @@ const run = async ({
23576
23671
  result.status = "aborted";
23577
23672
  }
23578
23673
  } else {
23579
- result.status = "errored";
23674
+ result.status = "failed";
23580
23675
  result.errors.push(e);
23581
23676
  }
23582
23677
  } finally {
@@ -23683,7 +23778,7 @@ const EXECUTION_COLORS = {
23683
23778
  executing: ANSI.BLUE,
23684
23779
  aborted: ANSI.MAGENTA,
23685
23780
  timedout: ANSI.MAGENTA,
23686
- errored: ANSI.RED,
23781
+ failed: ANSI.RED,
23687
23782
  completed: ANSI.GREEN,
23688
23783
  cancelled: ANSI.GREY
23689
23784
  };
@@ -23816,8 +23911,8 @@ const createStatusSummary = ({
23816
23911
  if (counters.timedout === counters.total) {
23817
23912
  return `all ${ANSI.color(`timed out`, EXECUTION_COLORS.timedout)}`;
23818
23913
  }
23819
- if (counters.errored === counters.total) {
23820
- return `all ${ANSI.color(`errored`, EXECUTION_COLORS.errored)}`;
23914
+ if (counters.failed === counters.total) {
23915
+ return `all ${ANSI.color(`failed`, EXECUTION_COLORS.failed)}`;
23821
23916
  }
23822
23917
  if (counters.completed === counters.total) {
23823
23918
  return `all ${ANSI.color(`completed`, EXECUTION_COLORS.completed)}`;
@@ -23836,8 +23931,8 @@ const createMixedDetails = ({
23836
23931
  if (counters.timedout) {
23837
23932
  parts.push(`${counters.timedout} ${ANSI.color(`timed out`, EXECUTION_COLORS.timedout)}`);
23838
23933
  }
23839
- if (counters.errored) {
23840
- parts.push(`${counters.errored} ${ANSI.color(`errored`, EXECUTION_COLORS.errored)}`);
23934
+ if (counters.failed) {
23935
+ parts.push(`${counters.failed} ${ANSI.color(`failed`, EXECUTION_COLORS.failed)}`);
23841
23936
  }
23842
23937
  if (counters.completed) {
23843
23938
  parts.push(`${counters.completed} ${ANSI.color(`completed`, EXECUTION_COLORS.completed)}`);
@@ -23870,11 +23965,11 @@ const descriptionFormatters = {
23870
23965
  }) => {
23871
23966
  return ANSI.color(`${UNICODE.FAILURE_RAW} execution ${index + 1} of ${total} timeout after ${executionParams.allocatedMs}ms`, EXECUTION_COLORS.timedout);
23872
23967
  },
23873
- errored: ({
23968
+ efailedrrored: ({
23874
23969
  index,
23875
23970
  total
23876
23971
  }) => {
23877
- return ANSI.color(`${UNICODE.FAILURE_RAW} execution ${index + 1} of ${total} errored`, EXECUTION_COLORS.errored);
23972
+ return ANSI.color(`${UNICODE.FAILURE_RAW} execution ${index + 1} of ${total} failed`, EXECUTION_COLORS.failed);
23878
23973
  },
23879
23974
  completed: ({
23880
23975
  index,
@@ -24193,7 +24288,7 @@ const executePlan = async (plan, {
24193
24288
  total: executionSteps.length,
24194
24289
  aborted: 0,
24195
24290
  timedout: 0,
24196
- errored: 0,
24291
+ failed: 0,
24197
24292
  completed: 0,
24198
24293
  done: 0
24199
24294
  };
@@ -24276,7 +24371,7 @@ const executePlan = async (plan, {
24276
24371
  });
24277
24372
  } else {
24278
24373
  executionResult = {
24279
- status: "errored",
24374
+ status: "failed",
24280
24375
  errors: [new Error(`No file at ${fileRelativeUrl} for execution "${executionName}"`)]
24281
24376
  };
24282
24377
  }
@@ -24300,8 +24395,8 @@ const executePlan = async (plan, {
24300
24395
  counters.aborted++;
24301
24396
  } else if (executionResult.status === "timedout") {
24302
24397
  counters.timedout++;
24303
- } else if (executionResult.status === "errored") {
24304
- counters.errored++;
24398
+ } else if (executionResult.status === "failed") {
24399
+ counters.failed++;
24305
24400
  } else if (executionResult.status === "completed") {
24306
24401
  counters.completed++;
24307
24402
  }
@@ -24536,46 +24631,58 @@ const executeTestPlan = async ({
24536
24631
  coverageReportSkipFull = false,
24537
24632
  coverageReportTextLog = true,
24538
24633
  coverageReportJsonFile = process.env.CI ? null : "./.coverage/coverage.json",
24539
- coverageReportHtmlDirectory = process.env.CI ? "./.coverage/" : null
24634
+ coverageReportHtmlDirectory = process.env.CI ? "./.coverage/" : null,
24635
+ ...rest
24540
24636
  }) => {
24541
- const logger = createLogger({
24542
- logLevel
24543
- });
24544
- rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl);
24545
- if (typeof testPlan !== "object") {
24546
- throw new Error(`testPlan must be an object, got ${testPlan}`);
24547
- }
24548
- if (coverageEnabled) {
24549
- if (typeof coverageConfig !== "object") {
24550
- throw new TypeError(`coverageConfig must be an object, got ${coverageConfig}`);
24551
- }
24552
- if (Object.keys(coverageConfig).length === 0) {
24553
- logger.warn(`coverageConfig is an empty object. Nothing will be instrumented for coverage so your coverage will be empty`);
24554
- }
24555
- if (!coverageAndExecutionAllowed) {
24556
- const associationsForExecute = URL_META.resolveAssociations({
24557
- execute: testPlan
24558
- }, "file:///");
24559
- const associationsForCover = URL_META.resolveAssociations({
24560
- cover: coverageConfig
24561
- }, "file:///");
24562
- const patternsMatchingCoverAndExecute = Object.keys(associationsForExecute.execute).filter(testPlanPattern => {
24563
- const {
24564
- cover
24565
- } = URL_META.applyAssociations({
24566
- url: testPlanPattern,
24567
- associations: associationsForCover
24637
+ // param validation
24638
+ {
24639
+ const unexpectedParamNames = Object.keys(rest);
24640
+ if (unexpectedParamNames.length > 0) {
24641
+ throw new TypeError(`${unexpectedParamNames.join(",")}: there is no such param`);
24642
+ }
24643
+ const rootDirectoryUrlValidation = validateDirectoryUrl(rootDirectoryUrl);
24644
+ if (!rootDirectoryUrlValidation.valid) {
24645
+ throw new TypeError(`rootDirectoryUrl ${rootDirectoryUrlValidation.message}, got ${rootDirectoryUrl}`);
24646
+ }
24647
+ rootDirectoryUrl = rootDirectoryUrlValidation.value;
24648
+ if (typeof testPlan !== "object") {
24649
+ throw new Error(`testPlan must be an object, got ${testPlan}`);
24650
+ }
24651
+ if (coverageEnabled) {
24652
+ if (typeof coverageConfig !== "object") {
24653
+ throw new TypeError(`coverageConfig must be an object, got ${coverageConfig}`);
24654
+ }
24655
+ if (!coverageAndExecutionAllowed) {
24656
+ const associationsForExecute = URL_META.resolveAssociations({
24657
+ execute: testPlan
24658
+ }, "file:///");
24659
+ const associationsForCover = URL_META.resolveAssociations({
24660
+ cover: coverageConfig
24661
+ }, "file:///");
24662
+ const patternsMatchingCoverAndExecute = Object.keys(associationsForExecute.execute).filter(testPlanPattern => {
24663
+ const {
24664
+ cover
24665
+ } = URL_META.applyAssociations({
24666
+ url: testPlanPattern,
24667
+ associations: associationsForCover
24668
+ });
24669
+ return cover;
24568
24670
  });
24569
- return cover;
24570
- });
24571
- if (patternsMatchingCoverAndExecute.length) {
24572
- // It would be strange, for a given file to be both covered and executed
24573
- throw new Error(createDetailedMessage$1(`some file will be both covered and executed`, {
24574
- patterns: patternsMatchingCoverAndExecute
24575
- }));
24671
+ if (patternsMatchingCoverAndExecute.length) {
24672
+ // It would be strange, for a given file to be both covered and executed
24673
+ throw new Error(createDetailedMessage$1(`some file will be both covered and executed`, {
24674
+ patterns: patternsMatchingCoverAndExecute
24675
+ }));
24676
+ }
24576
24677
  }
24577
24678
  }
24578
24679
  }
24680
+ const logger = createLogger({
24681
+ logLevel
24682
+ });
24683
+ if (Object.keys(coverageConfig).length === 0) {
24684
+ logger.warn(`coverageConfig is an empty object. Nothing will be instrumented for coverage so your coverage will be empty`);
24685
+ }
24579
24686
  const result = await executePlan(testPlan, {
24580
24687
  signal,
24581
24688
  handleSIGINT,
@@ -24955,12 +25062,12 @@ const createRuntimeFromPlaywright = ({
24955
25062
  }
24956
25063
  if (winner.name === "error") {
24957
25064
  let error = winner.data;
24958
- result.status = "errored";
25065
+ result.status = "failed";
24959
25066
  result.errors.push(error);
24960
25067
  return;
24961
25068
  }
24962
25069
  if (winner.name === "closed") {
24963
- result.status = "errored";
25070
+ result.status = "failed";
24964
25071
  result.errors.push(isBrowserDedicatedToExecution ? new Error(`browser disconnected during execution`) : new Error(`page closed during execution`));
24965
25072
  return;
24966
25073
  }
@@ -24972,8 +25079,8 @@ const createRuntimeFromPlaywright = ({
24972
25079
  result.namespace = executionResults;
24973
25080
  Object.keys(executionResults).forEach(key => {
24974
25081
  const executionResult = executionResults[key];
24975
- if (executionResult.status === "errored") {
24976
- result.status = "errored";
25082
+ if (executionResult.status === "failed") {
25083
+ result.status = "failed";
24977
25084
  result.errors.push({
24978
25085
  ...executionResult.exception,
24979
25086
  stack: executionResult.exception.text
@@ -24991,7 +25098,7 @@ const createRuntimeFromPlaywright = ({
24991
25098
  await callback();
24992
25099
  }, Promise.resolve());
24993
25100
  } catch (e) {
24994
- result.status = "errored";
25101
+ result.status = "failed";
24995
25102
  result.errors = [e];
24996
25103
  }
24997
25104
  if (keepRunning) {
@@ -25620,7 +25727,7 @@ nodeChildProcess.run = async ({
25620
25727
  if (winner.name === "error") {
25621
25728
  const error = winner.data;
25622
25729
  removeOutputListener();
25623
- result.status = "errored";
25730
+ result.status = "failed";
25624
25731
  result.errors.push(error);
25625
25732
  return;
25626
25733
  }
@@ -25630,18 +25737,18 @@ nodeChildProcess.run = async ({
25630
25737
  } = winner.data;
25631
25738
  await cleanup("process exit");
25632
25739
  if (code === 12) {
25633
- result.status = "errored";
25740
+ result.status = "failed";
25634
25741
  result.errors.push(new Error(`node process exited with 12 (the forked child process wanted to use a non-available port for debug)`));
25635
25742
  return;
25636
25743
  }
25637
25744
  if (code === null || code === 0 || code === EXIT_CODES.SIGINT || code === EXIT_CODES.SIGTERM || code === EXIT_CODES.SIGABORT) {
25638
- result.status = "errored";
25745
+ result.status = "failed";
25639
25746
  result.errors.push(new Error(`node process exited during execution`));
25640
25747
  return;
25641
25748
  }
25642
25749
  // process.exit(1) in child process or process.exitCode = 1 + process.exit()
25643
25750
  // means there was an error even if we don't know exactly what.
25644
- result.status = "errored";
25751
+ result.status = "failed";
25645
25752
  result.errors.push(new Error(`node process exited with code ${code} during execution`));
25646
25753
  return;
25647
25754
  }
@@ -25650,7 +25757,7 @@ nodeChildProcess.run = async ({
25650
25757
  value
25651
25758
  } = winner.data;
25652
25759
  if (status === "action-failed") {
25653
- result.status = "errored";
25760
+ result.status = "failed";
25654
25761
  result.errors.push(value);
25655
25762
  return;
25656
25763
  }
@@ -25667,7 +25774,7 @@ nodeChildProcess.run = async ({
25667
25774
  try {
25668
25775
  await writeResult();
25669
25776
  } catch (e) {
25670
- result.status = "errored";
25777
+ result.status = "failed";
25671
25778
  result.errors.push(e);
25672
25779
  }
25673
25780
  if (keepRunning) {
@@ -25893,7 +26000,7 @@ nodeWorkerThread.run = async ({
25893
26000
  if (winner.name === "error") {
25894
26001
  const error = winner.data;
25895
26002
  removeOutputListener();
25896
- result.status = "errored";
26003
+ result.status = "failed";
25897
26004
  result.errors.push(error);
25898
26005
  return;
25899
26006
  }
@@ -25903,18 +26010,18 @@ nodeWorkerThread.run = async ({
25903
26010
  } = winner.data;
25904
26011
  await cleanup("process exit");
25905
26012
  if (code === 12) {
25906
- result.status = "errored";
26013
+ result.status = "failed";
25907
26014
  result.errors.push(new Error(`node process exited with 12 (the forked child process wanted to use a non-available port for debug)`));
25908
26015
  return;
25909
26016
  }
25910
26017
  if (code === null || code === 0 || code === EXIT_CODES.SIGINT || code === EXIT_CODES.SIGTERM || code === EXIT_CODES.SIGABORT) {
25911
- result.status = "errored";
26018
+ result.status = "failed";
25912
26019
  result.errors.push(new Error(`node worker thread exited during execution`));
25913
26020
  return;
25914
26021
  }
25915
26022
  // process.exit(1) in child process or process.exitCode = 1 + process.exit()
25916
26023
  // means there was an error even if we don't know exactly what.
25917
- result.status = "errored";
26024
+ result.status = "failed";
25918
26025
  result.errors.push(new Error(`node worker thread exited with code ${code} during execution`));
25919
26026
  }
25920
26027
  const {
@@ -25922,7 +26029,7 @@ nodeWorkerThread.run = async ({
25922
26029
  value
25923
26030
  } = winner.data;
25924
26031
  if (status === "action-failed") {
25925
- result.status = "errored";
26032
+ result.status = "failed";
25926
26033
  result.errors.push(value);
25927
26034
  return;
25928
26035
  }
@@ -25939,7 +26046,7 @@ nodeWorkerThread.run = async ({
25939
26046
  try {
25940
26047
  await writeResult();
25941
26048
  } catch (e) {
25942
- result.status = "errored";
26049
+ result.status = "failed";
25943
26050
  result.errors.push(e);
25944
26051
  }
25945
26052
  if (keepRunning) {
@@ -26030,10 +26137,8 @@ const startBuildServer = async ({
26030
26137
  handleSIGINT = true,
26031
26138
  logLevel,
26032
26139
  serverLogLevel = "warn",
26033
- protocol = "http",
26140
+ https,
26034
26141
  http2,
26035
- certificate,
26036
- privateKey,
26037
26142
  acceptAnyIp,
26038
26143
  hostname,
26039
26144
  port = 9779,
@@ -26160,10 +26265,8 @@ const startBuildServer = async ({
26160
26265
  keepProcessAlive,
26161
26266
  logLevel: serverLogLevel,
26162
26267
  startLog: false,
26163
- protocol,
26268
+ https,
26164
26269
  http2,
26165
- certificate,
26166
- privateKey,
26167
26270
  acceptAnyIp,
26168
26271
  hostname,
26169
26272
  port,
@@ -26303,7 +26406,7 @@ const execute = async ({
26303
26406
  });
26304
26407
  result = resultTransformer(result);
26305
26408
  try {
26306
- if (result.status === "errored") {
26409
+ if (result.status === "failed") {
26307
26410
  if (ignoreError) {
26308
26411
  return result;
26309
26412
  }