@cucumber/cucumber 8.5.1 → 8.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/lib/api/convert_configuration.js.map +1 -1
  2. package/lib/api/formatters.d.ts +1 -1
  3. package/lib/api/formatters.js +1 -36
  4. package/lib/api/formatters.js.map +1 -1
  5. package/lib/api/plugins.d.ts +4 -0
  6. package/lib/api/plugins.js +19 -0
  7. package/lib/api/plugins.js.map +1 -0
  8. package/lib/api/run_cucumber.js +9 -4
  9. package/lib/api/run_cucumber.js.map +1 -1
  10. package/lib/api/types.d.ts +6 -7
  11. package/lib/api/types.js.map +1 -1
  12. package/lib/formatter/index.d.ts +8 -9
  13. package/lib/formatter/index.js.map +1 -1
  14. package/lib/plugin/index.d.ts +2 -0
  15. package/lib/plugin/index.js +19 -0
  16. package/lib/plugin/index.js.map +1 -0
  17. package/lib/plugin/plugin_manager.d.ts +13 -0
  18. package/lib/plugin/plugin_manager.js +36 -0
  19. package/lib/plugin/plugin_manager.js.map +1 -0
  20. package/lib/plugin/types.d.ts +14 -0
  21. package/lib/plugin/types.js +3 -0
  22. package/lib/plugin/types.js.map +1 -0
  23. package/lib/{formatter → publish}/http_stream.d.ts +0 -0
  24. package/lib/{formatter → publish}/http_stream.js +0 -0
  25. package/lib/publish/http_stream.js.map +1 -0
  26. package/lib/publish/index.d.ts +2 -0
  27. package/lib/publish/index.js +5 -0
  28. package/lib/publish/index.js.map +1 -0
  29. package/lib/publish/publish_plugin.d.ts +2 -0
  30. package/lib/publish/publish_plugin.js +48 -0
  31. package/lib/publish/publish_plugin.js.map +1 -0
  32. package/lib/time.d.ts +7 -1
  33. package/lib/time.js.map +1 -1
  34. package/lib/version.d.ts +1 -1
  35. package/lib/version.js +1 -1
  36. package/lib/version.js.map +1 -1
  37. package/package.json +15 -11
  38. package/lib/formatter/http_stream.js.map +0 -1
  39. package/lib/formatter/publish.d.ts +0 -1
  40. package/lib/formatter/publish.js +0 -5
  41. package/lib/formatter/publish.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"convert_configuration.js","sourceRoot":"","sources":["../../src/api/convert_configuration.ts"],"names":[],"mappings":";;;AAAA,oDAIyB;AAGlB,KAAK,UAAU,oBAAoB,CACxC,iBAAiC,EACjC,GAAsB;IAEtB,OAAO;QACL,OAAO,EAAE;YACP,KAAK,EAAE,iBAAiB,CAAC,KAAK;YAC9B,cAAc,EAAE,iBAAiB,CAAC,QAAQ;YAC1C,KAAK,EAAE,iBAAiB,CAAC,IAAI;YAC7B,aAAa,EAAE,iBAAiB,CAAC,IAAI;YACrC,KAAK,EAAE,iBAAiB,CAAC,KAAK;SAC/B;QACD,OAAO,EAAE;YACP,cAAc,EAAE,iBAAiB,CAAC,aAAa;YAC/C,YAAY,EAAE,iBAAiB,CAAC,OAAO;YACvC,WAAW,EAAE,iBAAiB,CAAC,MAAM;SACtC;QACD,OAAO,EAAE;YACP,MAAM,EAAE,iBAAiB,CAAC,MAAM;YAChC,QAAQ,EAAE,iBAAiB,CAAC,QAAQ;YACpC,iBAAiB,EAAE,CAAC,iBAAiB,CAAC,SAAS;YAC/C,QAAQ,EAAE,iBAAiB,CAAC,QAAQ;YACpC,KAAK,EAAE,iBAAiB,CAAC,KAAK;YAC9B,cAAc,EAAE,iBAAiB,CAAC,cAAc;YAChD,MAAM,EAAE,iBAAiB,CAAC,MAAM;YAChC,eAAe,EAAE,iBAAiB,CAAC,eAAe;SACnD;QACD,OAAO,EAAE,cAAc,CAAC,iBAAiB,EAAE,GAAG,CAAC;KAChD,CAAA;AACH,CAAC;AA7BD,oDA6BC;AAED,SAAS,cAAc,CACrB,iBAAiC,EACjC,GAAsB;;IAEtB,MAAM,YAAY,GAAe,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACrE,8BAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAC3B,CAAA;IACD,OAAO;QACL,MAAM,EACJ,MAAA,MAAA,CAAC,GAAG,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,0CAAG,CAAC,CAAC,mCAC9D,UAAU;QACZ,KAAK,EAAE,YAAY;aAChB,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;aAChC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE;YACjC,OAAO;gBACL,GAAG,MAAM;gBACT,CAAC,MAAM,CAAC,EAAE,IAAI;aACf,CAAA;QACH,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,GAAG,CAAC;QAClD,OAAO,EAAE,iBAAiB,CAAC,aAAa;KACzC,CAAA;AACH,CAAC;AAED,SAAS,iBAAiB,CACxB,iBAAiC,EACjC,GAAsB;IAEtB,MAAM,OAAO,GAAG,YAAY,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAA;IACpD,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,KAAK,CAAA;KACb;IACD,OAAO;QACL,GAAG,EAAE,GAAG,CAAC,oBAAoB;QAC7B,KAAK,EAAE,GAAG,CAAC,sBAAsB;KAClC,CAAA;AACH,CAAC;AAED,SAAS,YAAY,CACnB,iBAAiC,EACjC,GAAsB;IAEtB,OAAO,CACL,iBAAiB,CAAC,OAAO;QACzB,IAAA,8BAAc,EAAC,GAAG,CAAC,wBAAwB,CAAC;QAC5C,GAAG,CAAC,sBAAsB,KAAK,SAAS,CACzC,CAAA;AACH,CAAC","sourcesContent":["import {\n IConfiguration,\n isTruthyString,\n OptionSplitter,\n} from '../configuration'\nimport { IRunConfiguration } from './types'\n\nexport async function convertConfiguration(\n flatConfiguration: IConfiguration,\n env: NodeJS.ProcessEnv\n): Promise<IRunConfiguration> {\n return {\n sources: {\n paths: flatConfiguration.paths,\n defaultDialect: flatConfiguration.language,\n names: flatConfiguration.name,\n tagExpression: flatConfiguration.tags,\n order: flatConfiguration.order,\n },\n support: {\n requireModules: flatConfiguration.requireModule,\n requirePaths: flatConfiguration.require,\n importPaths: flatConfiguration.import,\n },\n runtime: {\n dryRun: flatConfiguration.dryRun,\n failFast: flatConfiguration.failFast,\n filterStacktraces: !flatConfiguration.backtrace,\n parallel: flatConfiguration.parallel,\n retry: flatConfiguration.retry,\n retryTagFilter: flatConfiguration.retryTagFilter,\n strict: flatConfiguration.strict,\n worldParameters: flatConfiguration.worldParameters,\n },\n formats: convertFormats(flatConfiguration, env),\n }\n}\n\nfunction convertFormats(\n flatConfiguration: IConfiguration,\n env: NodeJS.ProcessEnv\n) {\n const splitFormats: string[][] = flatConfiguration.format.map((item) =>\n OptionSplitter.split(item)\n )\n return {\n stdout:\n [...splitFormats].reverse().find(([, target]) => !target)?.[0] ??\n 'progress',\n files: splitFormats\n .filter(([, target]) => !!target)\n .reduce((mapped, [type, target]) => {\n return {\n ...mapped,\n [target]: type,\n }\n }, {}),\n publish: makePublishConfig(flatConfiguration, env),\n options: flatConfiguration.formatOptions,\n }\n}\n\nfunction makePublishConfig(\n flatConfiguration: IConfiguration,\n env: NodeJS.ProcessEnv\n): any {\n const enabled = isPublishing(flatConfiguration, env)\n if (!enabled) {\n return false\n }\n return {\n url: env.CUCUMBER_PUBLISH_URL,\n token: env.CUCUMBER_PUBLISH_TOKEN,\n }\n}\n\nfunction isPublishing(\n flatConfiguration: IConfiguration,\n env: NodeJS.ProcessEnv\n): boolean {\n return (\n flatConfiguration.publish ||\n isTruthyString(env.CUCUMBER_PUBLISH_ENABLED) ||\n env.CUCUMBER_PUBLISH_TOKEN !== undefined\n )\n}\n"]}
1
+ {"version":3,"file":"convert_configuration.js","sourceRoot":"","sources":["../../src/api/convert_configuration.ts"],"names":[],"mappings":";;;AAAA,oDAIyB;AAIlB,KAAK,UAAU,oBAAoB,CACxC,iBAAiC,EACjC,GAAsB;IAEtB,OAAO;QACL,OAAO,EAAE;YACP,KAAK,EAAE,iBAAiB,CAAC,KAAK;YAC9B,cAAc,EAAE,iBAAiB,CAAC,QAAQ;YAC1C,KAAK,EAAE,iBAAiB,CAAC,IAAI;YAC7B,aAAa,EAAE,iBAAiB,CAAC,IAAI;YACrC,KAAK,EAAE,iBAAiB,CAAC,KAAK;SAC/B;QACD,OAAO,EAAE;YACP,cAAc,EAAE,iBAAiB,CAAC,aAAa;YAC/C,YAAY,EAAE,iBAAiB,CAAC,OAAO;YACvC,WAAW,EAAE,iBAAiB,CAAC,MAAM;SACtC;QACD,OAAO,EAAE;YACP,MAAM,EAAE,iBAAiB,CAAC,MAAM;YAChC,QAAQ,EAAE,iBAAiB,CAAC,QAAQ;YACpC,iBAAiB,EAAE,CAAC,iBAAiB,CAAC,SAAS;YAC/C,QAAQ,EAAE,iBAAiB,CAAC,QAAQ;YACpC,KAAK,EAAE,iBAAiB,CAAC,KAAK;YAC9B,cAAc,EAAE,iBAAiB,CAAC,cAAc;YAChD,MAAM,EAAE,iBAAiB,CAAC,MAAM;YAChC,eAAe,EAAE,iBAAiB,CAAC,eAAe;SACnD;QACD,OAAO,EAAE,cAAc,CAAC,iBAAiB,EAAE,GAAG,CAAC;KAChD,CAAA;AACH,CAAC;AA7BD,oDA6BC;AAED,SAAS,cAAc,CACrB,iBAAiC,EACjC,GAAsB;;IAEtB,MAAM,YAAY,GAAe,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACrE,8BAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAC3B,CAAA;IACD,OAAO;QACL,MAAM,EACJ,MAAA,MAAA,CAAC,GAAG,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,0CAAG,CAAC,CAAC,mCAC9D,UAAU;QACZ,KAAK,EAAE,YAAY;aAChB,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;aAChC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE;YACjC,OAAO;gBACL,GAAG,MAAM;gBACT,CAAC,MAAM,CAAC,EAAE,IAAI;aACf,CAAA;QACH,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,GAAG,CAAC;QAClD,OAAO,EAAE,iBAAiB,CAAC,aAAa;KACzC,CAAA;AACH,CAAC;AAED,SAAS,iBAAiB,CACxB,iBAAiC,EACjC,GAAsB;IAEtB,MAAM,OAAO,GAAG,YAAY,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAA;IACpD,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,KAAK,CAAA;KACb;IACD,OAAO;QACL,GAAG,EAAE,GAAG,CAAC,oBAAoB;QAC7B,KAAK,EAAE,GAAG,CAAC,sBAAsB;KAClC,CAAA;AACH,CAAC;AAED,SAAS,YAAY,CACnB,iBAAiC,EACjC,GAAsB;IAEtB,OAAO,CACL,iBAAiB,CAAC,OAAO;QACzB,IAAA,8BAAc,EAAC,GAAG,CAAC,wBAAwB,CAAC;QAC5C,GAAG,CAAC,sBAAsB,KAAK,SAAS,CACzC,CAAA;AACH,CAAC","sourcesContent":["import {\n IConfiguration,\n isTruthyString,\n OptionSplitter,\n} from '../configuration'\nimport { IPublishConfig } from '../formatter'\nimport { IRunConfiguration } from './types'\n\nexport async function convertConfiguration(\n flatConfiguration: IConfiguration,\n env: NodeJS.ProcessEnv\n): Promise<IRunConfiguration> {\n return {\n sources: {\n paths: flatConfiguration.paths,\n defaultDialect: flatConfiguration.language,\n names: flatConfiguration.name,\n tagExpression: flatConfiguration.tags,\n order: flatConfiguration.order,\n },\n support: {\n requireModules: flatConfiguration.requireModule,\n requirePaths: flatConfiguration.require,\n importPaths: flatConfiguration.import,\n },\n runtime: {\n dryRun: flatConfiguration.dryRun,\n failFast: flatConfiguration.failFast,\n filterStacktraces: !flatConfiguration.backtrace,\n parallel: flatConfiguration.parallel,\n retry: flatConfiguration.retry,\n retryTagFilter: flatConfiguration.retryTagFilter,\n strict: flatConfiguration.strict,\n worldParameters: flatConfiguration.worldParameters,\n },\n formats: convertFormats(flatConfiguration, env),\n }\n}\n\nfunction convertFormats(\n flatConfiguration: IConfiguration,\n env: NodeJS.ProcessEnv\n) {\n const splitFormats: string[][] = flatConfiguration.format.map((item) =>\n OptionSplitter.split(item)\n )\n return {\n stdout:\n [...splitFormats].reverse().find(([, target]) => !target)?.[0] ??\n 'progress',\n files: splitFormats\n .filter(([, target]) => !!target)\n .reduce((mapped, [type, target]) => {\n return {\n ...mapped,\n [target]: type,\n }\n }, {}),\n publish: makePublishConfig(flatConfiguration, env),\n options: flatConfiguration.formatOptions,\n }\n}\n\nfunction makePublishConfig(\n flatConfiguration: IConfiguration,\n env: NodeJS.ProcessEnv\n): IPublishConfig | false {\n const enabled = isPublishing(flatConfiguration, env)\n if (!enabled) {\n return false\n }\n return {\n url: env.CUCUMBER_PUBLISH_URL,\n token: env.CUCUMBER_PUBLISH_TOKEN,\n }\n}\n\nfunction isPublishing(\n flatConfiguration: IConfiguration,\n env: NodeJS.ProcessEnv\n): boolean {\n return (\n flatConfiguration.publish ||\n isTruthyString(env.CUCUMBER_PUBLISH_ENABLED) ||\n env.CUCUMBER_PUBLISH_TOKEN !== undefined\n )\n}\n"]}
@@ -6,7 +6,7 @@ import { EventEmitter } from 'events';
6
6
  import { EventDataCollector } from '../formatter/helpers';
7
7
  import { ISupportCodeLibrary } from '../support_code_library_builder/types';
8
8
  import { IRunOptionsFormats } from './types';
9
- export declare function initializeFormatters({ env, cwd, stdout, stderr, logger, onStreamError, eventBroadcaster, eventDataCollector, configuration, supportCodeLibrary, }: {
9
+ export declare function initializeFormatters({ env, cwd, stdout, logger, onStreamError, eventBroadcaster, eventDataCollector, configuration, supportCodeLibrary, }: {
10
10
  env: NodeJS.ProcessEnv;
11
11
  cwd: string;
12
12
  stdout: IFormatterStream;
@@ -8,13 +8,7 @@ const util_1 = require("util");
8
8
  const builder_1 = __importDefault(require("../formatter/builder"));
9
9
  const fs_1 = __importDefault(require("mz/fs"));
10
10
  const path_1 = __importDefault(require("path"));
11
- const publish_1 = require("../formatter/publish");
12
- const http_stream_1 = __importDefault(require("../formatter/http_stream"));
13
- const stream_1 = require("stream");
14
- const supports_color_1 = require("supports-color");
15
- const has_ansi_1 = __importDefault(require("has-ansi"));
16
- const strip_ansi_1 = __importDefault(require("strip-ansi"));
17
- async function initializeFormatters({ env, cwd, stdout, stderr, logger, onStreamError, eventBroadcaster, eventDataCollector, configuration, supportCodeLibrary, }) {
11
+ async function initializeFormatters({ env, cwd, stdout, logger, onStreamError, eventBroadcaster, eventDataCollector, configuration, supportCodeLibrary, }) {
18
12
  async function initializeFormatter(stream, target, type) {
19
13
  stream.on('error', (error) => {
20
14
  logger.error(error.message);
@@ -47,38 +41,9 @@ async function initializeFormatters({ env, cwd, stdout, stderr, logger, onStream
47
41
  });
48
42
  formatters.push(await initializeFormatter(stream, target, type));
49
43
  }
50
- if (configuration.publish) {
51
- const { url = publish_1.DEFAULT_CUCUMBER_PUBLISH_URL, token } = configuration.publish;
52
- const headers = {};
53
- if (token !== undefined) {
54
- headers.Authorization = `Bearer ${token}`;
55
- }
56
- const stream = new http_stream_1.default(url, 'GET', headers);
57
- const readerStream = new stream_1.Writable({
58
- objectMode: true,
59
- write: function (responseBody, encoding, writeCallback) {
60
- logger.error(sanitisePublishOutput(responseBody, stderr));
61
- writeCallback();
62
- },
63
- });
64
- stream.pipe(readerStream);
65
- formatters.push(await initializeFormatter(stream, url, 'message'));
66
- }
67
44
  return async function () {
68
45
  await Promise.all(formatters.map(async (f) => await f.finished()));
69
46
  };
70
47
  }
71
48
  exports.initializeFormatters = initializeFormatters;
72
- /*
73
- This is because the Cucumber Reports service returns a pre-formatted console message
74
- including ANSI escapes, so if our stderr stream doesn't support those we need to
75
- strip them back out. Ideally we should get structured data from the service and
76
- compose the console message on this end.
77
- */
78
- function sanitisePublishOutput(raw, stderr) {
79
- if (!(0, supports_color_1.supportsColor)(stderr) && (0, has_ansi_1.default)(raw)) {
80
- return (0, strip_ansi_1.default)(raw);
81
- }
82
- return raw;
83
- }
84
49
  //# sourceMappingURL=formatters.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../src/api/formatters.ts"],"names":[],"mappings":"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","sourcesContent":["import Formatter, { IFormatterStream } from '../formatter'\nimport { EventEmitter } from 'events'\nimport { EventDataCollector } from '../formatter/helpers'\nimport { ISupportCodeLibrary } from '../support_code_library_builder/types'\nimport { promisify } from 'util'\nimport { WriteStream as TtyWriteStream } from 'tty'\nimport FormatterBuilder from '../formatter/builder'\nimport fs from 'mz/fs'\nimport path from 'path'\nimport { DEFAULT_CUCUMBER_PUBLISH_URL } from '../formatter/publish'\nimport HttpStream from '../formatter/http_stream'\nimport { Writable } from 'stream'\nimport { supportsColor } from 'supports-color'\nimport { IRunOptionsFormats } from './types'\nimport hasAnsi from 'has-ansi'\nimport stripAnsi from 'strip-ansi'\n\nexport async function initializeFormatters({\n env,\n cwd,\n stdout,\n stderr,\n logger,\n onStreamError,\n eventBroadcaster,\n eventDataCollector,\n configuration,\n supportCodeLibrary,\n}: {\n env: NodeJS.ProcessEnv\n cwd: string\n stdout: IFormatterStream\n stderr: IFormatterStream\n logger: Console\n onStreamError: () => void\n eventBroadcaster: EventEmitter\n eventDataCollector: EventDataCollector\n configuration: IRunOptionsFormats\n supportCodeLibrary: ISupportCodeLibrary\n}): Promise<() => Promise<void>> {\n async function initializeFormatter(\n stream: IFormatterStream,\n target: string,\n type: string\n ): Promise<Formatter> {\n stream.on('error', (error: Error) => {\n logger.error(error.message)\n onStreamError()\n })\n const typeOptions = {\n env,\n cwd,\n eventBroadcaster,\n eventDataCollector,\n log: stream.write.bind(stream),\n parsedArgvOptions: configuration.options,\n stream,\n cleanup:\n stream === stdout\n ? async () => await Promise.resolve()\n : promisify<any>(stream.end.bind(stream)),\n supportCodeLibrary,\n }\n if (type === 'progress-bar' && !(stream as TtyWriteStream).isTTY) {\n logger.warn(\n `Cannot use 'progress-bar' formatter for output to '${target}' as not a TTY. Switching to 'progress' formatter.`\n )\n type = 'progress'\n }\n return await FormatterBuilder.build(type, typeOptions)\n }\n\n const formatters: Formatter[] = []\n\n formatters.push(\n await initializeFormatter(stdout, 'stdout', configuration.stdout)\n )\n\n for (const [target, type] of Object.entries(configuration.files)) {\n const stream: IFormatterStream = fs.createWriteStream(null, {\n fd: await fs.open(path.resolve(cwd, target), 'w'),\n })\n formatters.push(await initializeFormatter(stream, target, type))\n }\n\n if (configuration.publish) {\n const { url = DEFAULT_CUCUMBER_PUBLISH_URL, token } = configuration.publish\n const headers: { [key: string]: string } = {}\n if (token !== undefined) {\n headers.Authorization = `Bearer ${token}`\n }\n const stream = new HttpStream(url, 'GET', headers)\n const readerStream = new Writable({\n objectMode: true,\n write: function (responseBody: string, encoding, writeCallback) {\n logger.error(sanitisePublishOutput(responseBody, stderr))\n writeCallback()\n },\n })\n stream.pipe(readerStream)\n formatters.push(await initializeFormatter(stream, url, 'message'))\n }\n\n return async function () {\n await Promise.all(formatters.map(async (f) => await f.finished()))\n }\n}\n\n/*\nThis is because the Cucumber Reports service returns a pre-formatted console message\nincluding ANSI escapes, so if our stderr stream doesn't support those we need to\nstrip them back out. Ideally we should get structured data from the service and\ncompose the console message on this end.\n */\nfunction sanitisePublishOutput(raw: string, stderr: IFormatterStream) {\n if (!supportsColor(stderr) && hasAnsi(raw)) {\n return stripAnsi(raw)\n }\n return raw\n}\n"]}
1
+ {"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../src/api/formatters.ts"],"names":[],"mappings":";;;;;;AAIA,+BAAgC;AAEhC,mEAAmD;AACnD,+CAAsB;AACtB,gDAAuB;AAGhB,KAAK,UAAU,oBAAoB,CAAC,EACzC,GAAG,EACH,GAAG,EACH,MAAM,EACN,MAAM,EACN,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,kBAAkB,GAYnB;IACC,KAAK,UAAU,mBAAmB,CAChC,MAAwB,EACxB,MAAc,EACd,IAAY;QAEZ,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;YAClC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YAC3B,aAAa,EAAE,CAAA;QACjB,CAAC,CAAC,CAAA;QACF,MAAM,WAAW,GAAG;YAClB,GAAG;YACH,GAAG;YACH,gBAAgB;YAChB,kBAAkB;YAClB,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;YAC9B,iBAAiB,EAAE,aAAa,CAAC,OAAO;YACxC,MAAM;YACN,OAAO,EACL,MAAM,KAAK,MAAM;gBACf,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE;gBACrC,CAAC,CAAC,IAAA,gBAAS,EAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7C,kBAAkB;SACnB,CAAA;QACD,IAAI,IAAI,KAAK,cAAc,IAAI,CAAE,MAAyB,CAAC,KAAK,EAAE;YAChE,MAAM,CAAC,IAAI,CACT,sDAAsD,MAAM,oDAAoD,CACjH,CAAA;YACD,IAAI,GAAG,UAAU,CAAA;SAClB;QACD,OAAO,MAAM,iBAAgB,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;IACxD,CAAC;IAED,MAAM,UAAU,GAAgB,EAAE,CAAA;IAElC,UAAU,CAAC,IAAI,CACb,MAAM,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAClE,CAAA;IAED,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE;QAChE,MAAM,MAAM,GAAqB,YAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE;YAC1D,EAAE,EAAE,MAAM,YAAE,CAAC,IAAI,CAAC,cAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC;SAClD,CAAC,CAAA;QACF,UAAU,CAAC,IAAI,CAAC,MAAM,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA;KACjE;IAED,OAAO,KAAK;QACV,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;IACpE,CAAC,CAAA;AACH,CAAC;AAtED,oDAsEC","sourcesContent":["import Formatter, { IFormatterStream } from '../formatter'\nimport { EventEmitter } from 'events'\nimport { EventDataCollector } from '../formatter/helpers'\nimport { ISupportCodeLibrary } from '../support_code_library_builder/types'\nimport { promisify } from 'util'\nimport { WriteStream as TtyWriteStream } from 'tty'\nimport FormatterBuilder from '../formatter/builder'\nimport fs from 'mz/fs'\nimport path from 'path'\nimport { IRunOptionsFormats } from './types'\n\nexport async function initializeFormatters({\n env,\n cwd,\n stdout,\n logger,\n onStreamError,\n eventBroadcaster,\n eventDataCollector,\n configuration,\n supportCodeLibrary,\n}: {\n env: NodeJS.ProcessEnv\n cwd: string\n stdout: IFormatterStream\n stderr: IFormatterStream\n logger: Console\n onStreamError: () => void\n eventBroadcaster: EventEmitter\n eventDataCollector: EventDataCollector\n configuration: IRunOptionsFormats\n supportCodeLibrary: ISupportCodeLibrary\n}): Promise<() => Promise<void>> {\n async function initializeFormatter(\n stream: IFormatterStream,\n target: string,\n type: string\n ): Promise<Formatter> {\n stream.on('error', (error: Error) => {\n logger.error(error.message)\n onStreamError()\n })\n const typeOptions = {\n env,\n cwd,\n eventBroadcaster,\n eventDataCollector,\n log: stream.write.bind(stream),\n parsedArgvOptions: configuration.options,\n stream,\n cleanup:\n stream === stdout\n ? async () => await Promise.resolve()\n : promisify<any>(stream.end.bind(stream)),\n supportCodeLibrary,\n }\n if (type === 'progress-bar' && !(stream as TtyWriteStream).isTTY) {\n logger.warn(\n `Cannot use 'progress-bar' formatter for output to '${target}' as not a TTY. Switching to 'progress' formatter.`\n )\n type = 'progress'\n }\n return await FormatterBuilder.build(type, typeOptions)\n }\n\n const formatters: Formatter[] = []\n\n formatters.push(\n await initializeFormatter(stdout, 'stdout', configuration.stdout)\n )\n\n for (const [target, type] of Object.entries(configuration.files)) {\n const stream: IFormatterStream = fs.createWriteStream(null, {\n fd: await fs.open(path.resolve(cwd, target), 'w'),\n })\n formatters.push(await initializeFormatter(stream, target, type))\n }\n\n return async function () {\n await Promise.all(formatters.map(async (f) => await f.finished()))\n }\n}\n"]}
@@ -0,0 +1,4 @@
1
+ /// <reference types="node" />
2
+ import { PluginManager } from '../plugin';
3
+ import { IRunEnvironment, IRunOptions } from './types';
4
+ export declare function initializePlugins(logger: Console, configuration: IRunOptions, environment: IRunEnvironment): Promise<PluginManager>;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.initializePlugins = void 0;
7
+ const plugin_1 = require("../plugin");
8
+ const publish_1 = __importDefault(require("../publish"));
9
+ const INTERNAL_PLUGINS = {
10
+ publish: publish_1.default,
11
+ };
12
+ async function initializePlugins(logger, configuration, environment) {
13
+ // eventually we'll load plugin packages here
14
+ const pluginManager = new plugin_1.PluginManager(Object.values(INTERNAL_PLUGINS));
15
+ await pluginManager.init(logger, configuration, environment);
16
+ return pluginManager;
17
+ }
18
+ exports.initializePlugins = initializePlugins;
19
+ //# sourceMappingURL=plugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../src/api/plugins.ts"],"names":[],"mappings":";;;;;;AAAA,sCAAiD;AACjD,yDAAsC;AAGtC,MAAM,gBAAgB,GAA2B;IAC/C,OAAO,EAAE,iBAAa;CACvB,CAAA;AAEM,KAAK,UAAU,iBAAiB,CACrC,MAAe,EACf,aAA0B,EAC1B,WAA4B;IAE5B,6CAA6C;IAC7C,MAAM,aAAa,GAAG,IAAI,sBAAa,CAAC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAA;IACxE,MAAM,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAA;IAC5D,OAAO,aAAa,CAAA;AACtB,CAAC;AATD,8CASC","sourcesContent":["import { Plugin, PluginManager } from '../plugin'\nimport publishPlugin from '../publish'\nimport { IRunEnvironment, IRunOptions } from './types'\n\nconst INTERNAL_PLUGINS: Record<string, Plugin> = {\n publish: publishPlugin,\n}\n\nexport async function initializePlugins(\n logger: Console,\n configuration: IRunOptions,\n environment: IRunEnvironment\n): Promise<PluginManager> {\n // eventually we'll load plugin packages here\n const pluginManager = new PluginManager(Object.values(INTERNAL_PLUGINS))\n await pluginManager.init(logger, configuration, environment)\n return pluginManager\n}\n"]}
@@ -12,6 +12,7 @@ const support_1 = require("./support");
12
12
  const console_1 = require("console");
13
13
  const environment_1 = require("./environment");
14
14
  const gherkin_1 = require("./gherkin");
15
+ const plugins_1 = require("./plugins");
15
16
  /**
16
17
  * Execute a Cucumber test run.
17
18
  *
@@ -22,7 +23,7 @@ const gherkin_1 = require("./gherkin");
22
23
  */
23
24
  async function runCucumber(configuration, environment = {}, onMessage) {
24
25
  const { cwd, stdout, stderr, env } = (0, environment_1.mergeEnvironment)(environment);
25
- const logger = new console_1.Console(stdout, stderr);
26
+ const logger = new console_1.Console(stderr);
26
27
  const newId = messages_1.IdGenerator.uuid();
27
28
  const supportCoordinates = 'World' in configuration.support
28
29
  ? configuration.support.originalCoordinates
@@ -37,13 +38,15 @@ async function runCucumber(configuration, environment = {}, onMessage) {
37
38
  importPaths,
38
39
  requireModules: supportCoordinates.requireModules,
39
40
  });
41
+ const plugins = await (0, plugins_1.initializePlugins)(logger, configuration, environment);
40
42
  const eventBroadcaster = new events_1.EventEmitter();
41
43
  if (onMessage) {
42
44
  eventBroadcaster.on('envelope', onMessage);
43
45
  }
46
+ eventBroadcaster.on('envelope', (value) => plugins.emit('message', value));
44
47
  const eventDataCollector = new helpers_1.EventDataCollector(eventBroadcaster);
45
48
  let formatterStreamError = false;
46
- const cleanup = await (0, formatters_1.initializeFormatters)({
49
+ const cleanupFormatters = await (0, formatters_1.initializeFormatters)({
47
50
  env,
48
51
  cwd,
49
52
  stdout,
@@ -75,7 +78,8 @@ async function runCucumber(configuration, environment = {}, onMessage) {
75
78
  parseErrors.forEach((parseError) => {
76
79
  logger.error(`Parse error in "${parseError.source.uri}" ${parseError.message}`);
77
80
  });
78
- await cleanup();
81
+ await cleanupFormatters();
82
+ await plugins.cleanup();
79
83
  return {
80
84
  success: false,
81
85
  support: supportCodeLibrary,
@@ -100,7 +104,8 @@ async function runCucumber(configuration, environment = {}, onMessage) {
100
104
  options: configuration.runtime,
101
105
  });
102
106
  const success = await runtime.start();
103
- await cleanup();
107
+ await cleanupFormatters();
108
+ await plugins.cleanup();
104
109
  return {
105
110
  success: success && !formatterStreamError,
106
111
  support: supportCodeLibrary,
@@ -1 +1 @@
1
- {"version":3,"file":"run_cucumber.js","sourceRoot":"","sources":["../../src/api/run_cucumber.ts"],"names":[],"mappings":"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","sourcesContent":["import { Envelope, IdGenerator, ParseError } from '@cucumber/messages'\nimport { EventEmitter } from 'events'\nimport { EventDataCollector } from '../formatter/helpers'\nimport { emitMetaMessage, emitSupportCodeMessages } from '../cli/helpers'\nimport { IRunOptions, IRunEnvironment, IRunResult } from './types'\nimport { resolvePaths } from './paths'\nimport { makeRuntime } from './runtime'\nimport { initializeFormatters } from './formatters'\nimport { getSupportCodeLibrary } from './support'\nimport { Console } from 'console'\nimport { mergeEnvironment } from './environment'\nimport { getFilteredPicklesAndErrors } from './gherkin'\n\n/**\n * Execute a Cucumber test run.\n *\n * @public\n * @param configuration - Configuration loaded from `loadConfiguration`.\n * @param environment - Project environment.\n * @param onMessage - Callback fired each time Cucumber emits a message.\n */\nexport async function runCucumber(\n configuration: IRunOptions,\n environment: IRunEnvironment = {},\n onMessage?: (message: Envelope) => void\n): Promise<IRunResult> {\n const { cwd, stdout, stderr, env } = mergeEnvironment(environment)\n const logger = new Console(stdout, stderr)\n const newId = IdGenerator.uuid()\n\n const supportCoordinates =\n 'World' in configuration.support\n ? configuration.support.originalCoordinates\n : configuration.support\n\n const { unexpandedFeaturePaths, featurePaths, requirePaths, importPaths } =\n await resolvePaths(cwd, configuration.sources, supportCoordinates)\n\n const supportCodeLibrary =\n 'World' in configuration.support\n ? configuration.support\n : await getSupportCodeLibrary({\n cwd,\n newId,\n requirePaths,\n importPaths,\n requireModules: supportCoordinates.requireModules,\n })\n\n const eventBroadcaster = new EventEmitter()\n if (onMessage) {\n eventBroadcaster.on('envelope', onMessage)\n }\n const eventDataCollector = new EventDataCollector(eventBroadcaster)\n\n let formatterStreamError = false\n const cleanup = await initializeFormatters({\n env,\n cwd,\n stdout,\n stderr,\n logger,\n onStreamError: () => (formatterStreamError = true),\n eventBroadcaster,\n eventDataCollector,\n configuration: configuration.formats,\n supportCodeLibrary,\n })\n await emitMetaMessage(eventBroadcaster, env)\n\n let pickleIds: string[] = []\n let parseErrors: ParseError[] = []\n if (featurePaths.length > 0) {\n const gherkinResult = await getFilteredPicklesAndErrors({\n newId,\n cwd,\n logger,\n unexpandedFeaturePaths,\n featurePaths,\n coordinates: configuration.sources,\n onEnvelope: (envelope) => eventBroadcaster.emit('envelope', envelope),\n })\n pickleIds = gherkinResult.filteredPickles.map(({ pickle }) => pickle.id)\n parseErrors = gherkinResult.parseErrors\n }\n if (parseErrors.length) {\n parseErrors.forEach((parseError) => {\n logger.error(\n `Parse error in \"${parseError.source.uri}\" ${parseError.message}`\n )\n })\n await cleanup()\n return {\n success: false,\n support: supportCodeLibrary,\n }\n }\n\n emitSupportCodeMessages({\n eventBroadcaster,\n supportCodeLibrary,\n newId,\n })\n\n const runtime = makeRuntime({\n cwd,\n logger,\n eventBroadcaster,\n eventDataCollector,\n pickleIds,\n newId,\n supportCodeLibrary,\n requireModules: supportCoordinates.requireModules,\n requirePaths,\n importPaths,\n options: configuration.runtime,\n })\n const success = await runtime.start()\n await cleanup()\n\n return {\n success: success && !formatterStreamError,\n support: supportCodeLibrary,\n }\n}\n"]}
1
+ {"version":3,"file":"run_cucumber.js","sourceRoot":"","sources":["../../src/api/run_cucumber.ts"],"names":[],"mappings":"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","sourcesContent":["import { Envelope, IdGenerator, ParseError } from '@cucumber/messages'\nimport { EventEmitter } from 'events'\nimport { EventDataCollector } from '../formatter/helpers'\nimport { emitMetaMessage, emitSupportCodeMessages } from '../cli/helpers'\nimport { IRunOptions, IRunEnvironment, IRunResult } from './types'\nimport { resolvePaths } from './paths'\nimport { makeRuntime } from './runtime'\nimport { initializeFormatters } from './formatters'\nimport { getSupportCodeLibrary } from './support'\nimport { Console } from 'console'\nimport { mergeEnvironment } from './environment'\nimport { getFilteredPicklesAndErrors } from './gherkin'\nimport { initializePlugins } from './plugins'\n\n/**\n * Execute a Cucumber test run.\n *\n * @public\n * @param configuration - Configuration loaded from `loadConfiguration`.\n * @param environment - Project environment.\n * @param onMessage - Callback fired each time Cucumber emits a message.\n */\nexport async function runCucumber(\n configuration: IRunOptions,\n environment: IRunEnvironment = {},\n onMessage?: (message: Envelope) => void\n): Promise<IRunResult> {\n const { cwd, stdout, stderr, env } = mergeEnvironment(environment)\n const logger = new Console(stderr)\n const newId = IdGenerator.uuid()\n\n const supportCoordinates =\n 'World' in configuration.support\n ? configuration.support.originalCoordinates\n : configuration.support\n\n const { unexpandedFeaturePaths, featurePaths, requirePaths, importPaths } =\n await resolvePaths(cwd, configuration.sources, supportCoordinates)\n\n const supportCodeLibrary =\n 'World' in configuration.support\n ? configuration.support\n : await getSupportCodeLibrary({\n cwd,\n newId,\n requirePaths,\n importPaths,\n requireModules: supportCoordinates.requireModules,\n })\n\n const plugins = await initializePlugins(logger, configuration, environment)\n\n const eventBroadcaster = new EventEmitter()\n if (onMessage) {\n eventBroadcaster.on('envelope', onMessage)\n }\n eventBroadcaster.on('envelope', (value) => plugins.emit('message', value))\n const eventDataCollector = new EventDataCollector(eventBroadcaster)\n\n let formatterStreamError = false\n const cleanupFormatters = await initializeFormatters({\n env,\n cwd,\n stdout,\n stderr,\n logger,\n onStreamError: () => (formatterStreamError = true),\n eventBroadcaster,\n eventDataCollector,\n configuration: configuration.formats,\n supportCodeLibrary,\n })\n await emitMetaMessage(eventBroadcaster, env)\n\n let pickleIds: string[] = []\n let parseErrors: ParseError[] = []\n if (featurePaths.length > 0) {\n const gherkinResult = await getFilteredPicklesAndErrors({\n newId,\n cwd,\n logger,\n unexpandedFeaturePaths,\n featurePaths,\n coordinates: configuration.sources,\n onEnvelope: (envelope) => eventBroadcaster.emit('envelope', envelope),\n })\n pickleIds = gherkinResult.filteredPickles.map(({ pickle }) => pickle.id)\n parseErrors = gherkinResult.parseErrors\n }\n if (parseErrors.length) {\n parseErrors.forEach((parseError) => {\n logger.error(\n `Parse error in \"${parseError.source.uri}\" ${parseError.message}`\n )\n })\n await cleanupFormatters()\n await plugins.cleanup()\n return {\n success: false,\n support: supportCodeLibrary,\n }\n }\n\n emitSupportCodeMessages({\n eventBroadcaster,\n supportCodeLibrary,\n newId,\n })\n\n const runtime = makeRuntime({\n cwd,\n logger,\n eventBroadcaster,\n eventDataCollector,\n pickleIds,\n newId,\n supportCodeLibrary,\n requireModules: supportCoordinates.requireModules,\n requirePaths,\n importPaths,\n options: configuration.runtime,\n })\n const success = await runtime.start()\n await cleanupFormatters()\n await plugins.cleanup()\n\n return {\n success: success && !formatterStreamError,\n support: supportCodeLibrary,\n }\n}\n"]}
@@ -1,9 +1,11 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { ISupportCodeLibrary } from '../support_code_library_builder/types';
3
- import { FormatOptions, IFormatterStream } from '../formatter';
4
+ import { FormatOptions, IPublishConfig } from '../formatter';
4
5
  import { PickleOrder } from '../models/pickle_order';
5
6
  import { IRuntimeOptions } from '../runtime';
6
7
  import { IConfiguration } from '../configuration';
8
+ import { Writable } from 'stream';
7
9
  /**
8
10
  * @public
9
11
  */
@@ -100,10 +102,7 @@ export interface IRunOptionsRuntime extends IRuntimeOptions {
100
102
  export interface IRunOptionsFormats {
101
103
  stdout: string;
102
104
  files: Record<string, string>;
103
- publish: {
104
- url?: string;
105
- token?: string;
106
- } | false;
105
+ publish: IPublishConfig | false;
107
106
  options: FormatOptions;
108
107
  }
109
108
  /**
@@ -141,11 +140,11 @@ export interface IRunEnvironment {
141
140
  /**
142
141
  * Writable stream where the test run's main output is written (defaults to `process.stdout` if omitted).
143
142
  */
144
- stdout?: IFormatterStream;
143
+ stdout?: Writable;
145
144
  /**
146
145
  * Writable stream where the test run's warning/error output is written (defaults to `process.stderr` if omitted).
147
146
  */
148
- stderr?: IFormatterStream;
147
+ stderr?: Writable;
149
148
  /**
150
149
  * Environment variables (defaults to `process.env` if omitted).
151
150
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"","sourcesContent":["import { ISupportCodeLibrary } from '../support_code_library_builder/types'\nimport { FormatOptions, IFormatterStream } from '../formatter'\nimport { PickleOrder } from '../models/pickle_order'\nimport { IRuntimeOptions } from '../runtime'\nimport { IConfiguration } from '../configuration'\n\n/**\n * @public\n */\nexport interface ILoadConfigurationOptions {\n /**\n * Path to load configuration file from (defaults to `cucumber.(js|cjs|mjs|json)` if omitted).\n */\n file?: string\n /**\n * Zero or more profile names from which to source configuration (if omitted or empty, the `default` profile will be used).\n */\n profiles?: string[]\n /**\n * Ad-hoc configuration options to be applied over the top of whatever is loaded from the configuration file/profiles.\n */\n provided?: Partial<IConfiguration>\n}\n\n/**\n * @public\n */\nexport interface IResolvedConfiguration {\n /**\n * The final flat configuration object resolved from the configuration file/profiles plus any extra provided.\n */\n useConfiguration: IConfiguration\n /**\n * The format that can be passed into `runCucumber`.\n */\n runConfiguration: IRunConfiguration\n}\n\n/**\n * @public\n */\nexport interface ISourcesCoordinates {\n defaultDialect: string\n paths: string[]\n names: string[]\n tagExpression: string\n order: PickleOrder\n}\n\n/**\n * @public\n */\nexport interface IPlannedPickle {\n name: string\n uri: string\n location: {\n line: number\n column?: number\n }\n}\n\n/**\n * @public\n */\nexport interface ISourcesError {\n uri: string\n location: {\n line: number\n column?: number\n }\n message: string\n}\n\n/**\n * @public\n */\nexport interface ILoadSourcesResult {\n plan: IPlannedPickle[]\n errors: ISourcesError[]\n}\n\n/**\n * @public\n */\nexport interface ISupportCodeCoordinates {\n requireModules: string[]\n requirePaths: string[]\n importPaths: string[]\n}\n\n/**\n * @public\n */\nexport interface ILoadSupportOptions {\n sources: ISourcesCoordinates\n support: ISupportCodeCoordinates\n}\n\n/**\n * @public\n */\nexport interface IRunOptionsRuntime extends IRuntimeOptions {\n parallel: number\n}\n\n/**\n * @public\n */\nexport interface IRunOptionsFormats {\n stdout: string\n files: Record<string, string>\n publish:\n | {\n url?: string\n token?: string\n }\n | false\n options: FormatOptions\n}\n\n/**\n * @public\n */\nexport interface IRunConfiguration {\n sources: ISourcesCoordinates\n support: ISupportCodeCoordinates\n runtime: IRunOptionsRuntime\n formats: IRunOptionsFormats\n}\n\n/**\n * @public\n */\nexport type ISupportCodeCoordinatesOrLibrary =\n | ISupportCodeCoordinates\n | ISupportCodeLibrary\n\n/**\n * @public\n */\nexport interface IRunOptions {\n sources: ISourcesCoordinates\n support: ISupportCodeCoordinatesOrLibrary\n runtime: IRunOptionsRuntime\n formats: IRunOptionsFormats\n}\n\n/**\n * Contextual data about the project environment.\n *\n * @public\n */\nexport interface IRunEnvironment {\n /**\n * Working directory for the project (defaults to `process.cwd()` if omitted).\n */\n cwd?: string\n /**\n * Writable stream where the test run's main output is written (defaults to `process.stdout` if omitted).\n */\n stdout?: IFormatterStream\n /**\n * Writable stream where the test run's warning/error output is written (defaults to `process.stderr` if omitted).\n */\n stderr?: IFormatterStream\n /**\n * Environment variables (defaults to `process.env` if omitted).\n */\n env?: NodeJS.ProcessEnv\n}\n\n/**\n * Result of a Cucumber test run.\n *\n * @public\n */\nexport interface IRunResult {\n /**\n * Whether the test run was overall successful i.e. no failed scenarios. The exact meaning can vary based on the `strict` configuration option.\n */\n success: boolean\n /**\n * The support code library that was used in the test run; can be reused in subsequent `runCucumber` calls.\n */\n support: ISupportCodeLibrary\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"","sourcesContent":["import { ISupportCodeLibrary } from '../support_code_library_builder/types'\nimport { FormatOptions, IPublishConfig } from '../formatter'\nimport { PickleOrder } from '../models/pickle_order'\nimport { IRuntimeOptions } from '../runtime'\nimport { IConfiguration } from '../configuration'\nimport { Writable } from 'stream'\n\n/**\n * @public\n */\nexport interface ILoadConfigurationOptions {\n /**\n * Path to load configuration file from (defaults to `cucumber.(js|cjs|mjs|json)` if omitted).\n */\n file?: string\n /**\n * Zero or more profile names from which to source configuration (if omitted or empty, the `default` profile will be used).\n */\n profiles?: string[]\n /**\n * Ad-hoc configuration options to be applied over the top of whatever is loaded from the configuration file/profiles.\n */\n provided?: Partial<IConfiguration>\n}\n\n/**\n * @public\n */\nexport interface IResolvedConfiguration {\n /**\n * The final flat configuration object resolved from the configuration file/profiles plus any extra provided.\n */\n useConfiguration: IConfiguration\n /**\n * The format that can be passed into `runCucumber`.\n */\n runConfiguration: IRunConfiguration\n}\n\n/**\n * @public\n */\nexport interface ISourcesCoordinates {\n defaultDialect: string\n paths: string[]\n names: string[]\n tagExpression: string\n order: PickleOrder\n}\n\n/**\n * @public\n */\nexport interface IPlannedPickle {\n name: string\n uri: string\n location: {\n line: number\n column?: number\n }\n}\n\n/**\n * @public\n */\nexport interface ISourcesError {\n uri: string\n location: {\n line: number\n column?: number\n }\n message: string\n}\n\n/**\n * @public\n */\nexport interface ILoadSourcesResult {\n plan: IPlannedPickle[]\n errors: ISourcesError[]\n}\n\n/**\n * @public\n */\nexport interface ISupportCodeCoordinates {\n requireModules: string[]\n requirePaths: string[]\n importPaths: string[]\n}\n\n/**\n * @public\n */\nexport interface ILoadSupportOptions {\n sources: ISourcesCoordinates\n support: ISupportCodeCoordinates\n}\n\n/**\n * @public\n */\nexport interface IRunOptionsRuntime extends IRuntimeOptions {\n parallel: number\n}\n\n/**\n * @public\n */\nexport interface IRunOptionsFormats {\n stdout: string\n files: Record<string, string>\n publish: IPublishConfig | false\n options: FormatOptions\n}\n\n/**\n * @public\n */\nexport interface IRunConfiguration {\n sources: ISourcesCoordinates\n support: ISupportCodeCoordinates\n runtime: IRunOptionsRuntime\n formats: IRunOptionsFormats\n}\n\n/**\n * @public\n */\nexport type ISupportCodeCoordinatesOrLibrary =\n | ISupportCodeCoordinates\n | ISupportCodeLibrary\n\n/**\n * @public\n */\nexport interface IRunOptions {\n sources: ISourcesCoordinates\n support: ISupportCodeCoordinatesOrLibrary\n runtime: IRunOptionsRuntime\n formats: IRunOptionsFormats\n}\n\n/**\n * Contextual data about the project environment.\n *\n * @public\n */\nexport interface IRunEnvironment {\n /**\n * Working directory for the project (defaults to `process.cwd()` if omitted).\n */\n cwd?: string\n /**\n * Writable stream where the test run's main output is written (defaults to `process.stdout` if omitted).\n */\n stdout?: Writable\n /**\n * Writable stream where the test run's warning/error output is written (defaults to `process.stderr` if omitted).\n */\n stderr?: Writable\n /**\n * Environment variables (defaults to `process.env` if omitted).\n */\n env?: NodeJS.ProcessEnv\n}\n\n/**\n * Result of a Cucumber test run.\n *\n * @public\n */\nexport interface IRunResult {\n /**\n * Whether the test run was overall successful i.e. no failed scenarios. The exact meaning can vary based on the `strict` configuration option.\n */\n success: boolean\n /**\n * The support code library that was used in the test run; can be reused in subsequent `runCucumber` calls.\n */\n support: ISupportCodeLibrary\n}\n"]}
@@ -1,16 +1,11 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- /// <reference types="node" />
4
- /// <reference types="node" />
5
3
  import { IColorFns } from './get_color_fns';
6
4
  import { EventDataCollector } from './helpers';
7
5
  import StepDefinitionSnippetBuilder from './step_definition_snippet_builder';
8
- import { PassThrough, Writable as WritableStream } from 'stream';
6
+ import { Writable } from 'stream';
9
7
  import { ISupportCodeLibrary } from '../support_code_library_builder/types';
10
- import { WriteStream as FsWriteStream } from 'fs';
11
- import { WriteStream as TtyWriteStream } from 'tty';
12
8
  import { EventEmitter } from 'events';
13
- import HttpStream from './http_stream';
14
9
  import { SnippetInterface } from './step_definition_snippet_builder/snippet_syntax';
15
10
  export interface FormatRerunOptions {
16
11
  separator?: string;
@@ -23,7 +18,11 @@ export interface FormatOptions {
23
18
  printAttachments?: boolean;
24
19
  [customKey: string]: any;
25
20
  }
26
- export declare type IFormatterStream = FsWriteStream | TtyWriteStream | PassThrough | HttpStream;
21
+ export interface IPublishConfig {
22
+ url: string;
23
+ token: string;
24
+ }
25
+ export declare type IFormatterStream = Writable;
27
26
  export declare type IFormatterLogFn = (buffer: string | Uint8Array) => void;
28
27
  export declare type IFormatterCleanupFn = () => Promise<any>;
29
28
  export interface IFormatterOptions {
@@ -34,7 +33,7 @@ export interface IFormatterOptions {
34
33
  log: IFormatterLogFn;
35
34
  parsedArgvOptions: FormatOptions;
36
35
  snippetBuilder: StepDefinitionSnippetBuilder;
37
- stream: WritableStream;
36
+ stream: Writable;
38
37
  cleanup: IFormatterCleanupFn;
39
38
  supportCodeLibrary: ISupportCodeLibrary;
40
39
  }
@@ -44,7 +43,7 @@ export default class Formatter {
44
43
  protected eventDataCollector: EventDataCollector;
45
44
  protected log: IFormatterLogFn;
46
45
  protected snippetBuilder: StepDefinitionSnippetBuilder;
47
- protected stream: WritableStream;
46
+ protected stream: Writable;
48
47
  protected supportCodeLibrary: ISupportCodeLibrary;
49
48
  protected printAttachments: boolean;
50
49
  private readonly cleanup;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/formatter/index.ts"],"names":[],"mappings":";;AASA,oDAAiD;AAqCjD,MAAqB,SAAS;IAY5B,YAAY,OAA0B;QACpC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QAChC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAA;QACtB,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAA;QACpD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAA;QACtB,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAA;QAC5C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC5B,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAA;QACpD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;QAC9B,IAAI,CAAC,gBAAgB,GAAG,IAAA,8BAAc,EACpC,OAAO,CAAC,iBAAiB,CAAC,gBAAgB,EAC1C,IAAI,CACL,CAAA;IACH,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;IACtB,CAAC;CACF;AA9BD,4BA8BC","sourcesContent":["import { IColorFns } from './get_color_fns'\nimport { EventDataCollector } from './helpers'\nimport StepDefinitionSnippetBuilder from './step_definition_snippet_builder'\nimport { PassThrough, Writable as WritableStream } from 'stream'\nimport { ISupportCodeLibrary } from '../support_code_library_builder/types'\nimport { WriteStream as FsWriteStream } from 'fs'\nimport { WriteStream as TtyWriteStream } from 'tty'\nimport { EventEmitter } from 'events'\nimport HttpStream from './http_stream'\nimport { valueOrDefault } from '../value_checker'\nimport { SnippetInterface } from './step_definition_snippet_builder/snippet_syntax'\n\nexport interface FormatRerunOptions {\n separator?: string\n}\n\nexport interface FormatOptions {\n colorsEnabled?: boolean\n rerun?: FormatRerunOptions\n snippetInterface?: SnippetInterface\n snippetSyntax?: string\n printAttachments?: boolean\n [customKey: string]: any\n}\n\nexport type IFormatterStream =\n | FsWriteStream\n | TtyWriteStream\n | PassThrough\n | HttpStream\nexport type IFormatterLogFn = (buffer: string | Uint8Array) => void\nexport type IFormatterCleanupFn = () => Promise<any>\n\nexport interface IFormatterOptions {\n colorFns: IColorFns\n cwd: string\n eventBroadcaster: EventEmitter\n eventDataCollector: EventDataCollector\n log: IFormatterLogFn\n parsedArgvOptions: FormatOptions\n snippetBuilder: StepDefinitionSnippetBuilder\n stream: WritableStream\n cleanup: IFormatterCleanupFn\n supportCodeLibrary: ISupportCodeLibrary\n}\n\nexport default class Formatter {\n protected colorFns: IColorFns\n protected cwd: string\n protected eventDataCollector: EventDataCollector\n protected log: IFormatterLogFn\n protected snippetBuilder: StepDefinitionSnippetBuilder\n protected stream: WritableStream\n protected supportCodeLibrary: ISupportCodeLibrary\n protected printAttachments: boolean\n private readonly cleanup: IFormatterCleanupFn\n static readonly documentation: string\n\n constructor(options: IFormatterOptions) {\n this.colorFns = options.colorFns\n this.cwd = options.cwd\n this.eventDataCollector = options.eventDataCollector\n this.log = options.log\n this.snippetBuilder = options.snippetBuilder\n this.stream = options.stream\n this.supportCodeLibrary = options.supportCodeLibrary\n this.cleanup = options.cleanup\n this.printAttachments = valueOrDefault(\n options.parsedArgvOptions.printAttachments,\n true\n )\n }\n\n async finished(): Promise<void> {\n await this.cleanup()\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/formatter/index.ts"],"names":[],"mappings":";;AAMA,oDAAiD;AAsCjD,MAAqB,SAAS;IAY5B,YAAY,OAA0B;QACpC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QAChC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAA;QACtB,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAA;QACpD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAA;QACtB,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAA;QAC5C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC5B,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAA;QACpD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;QAC9B,IAAI,CAAC,gBAAgB,GAAG,IAAA,8BAAc,EACpC,OAAO,CAAC,iBAAiB,CAAC,gBAAgB,EAC1C,IAAI,CACL,CAAA;IACH,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;IACtB,CAAC;CACF;AA9BD,4BA8BC","sourcesContent":["import { IColorFns } from './get_color_fns'\nimport { EventDataCollector } from './helpers'\nimport StepDefinitionSnippetBuilder from './step_definition_snippet_builder'\nimport { Writable } from 'stream'\nimport { ISupportCodeLibrary } from '../support_code_library_builder/types'\nimport { EventEmitter } from 'events'\nimport { valueOrDefault } from '../value_checker'\nimport { SnippetInterface } from './step_definition_snippet_builder/snippet_syntax'\n\nexport interface FormatRerunOptions {\n separator?: string\n}\n\nexport interface FormatOptions {\n colorsEnabled?: boolean\n rerun?: FormatRerunOptions\n snippetInterface?: SnippetInterface\n snippetSyntax?: string\n printAttachments?: boolean\n [customKey: string]: any\n}\n\nexport interface IPublishConfig {\n url: string\n token: string\n}\n\nexport type IFormatterStream = Writable\nexport type IFormatterLogFn = (buffer: string | Uint8Array) => void\nexport type IFormatterCleanupFn = () => Promise<any>\n\nexport interface IFormatterOptions {\n colorFns: IColorFns\n cwd: string\n eventBroadcaster: EventEmitter\n eventDataCollector: EventDataCollector\n log: IFormatterLogFn\n parsedArgvOptions: FormatOptions\n snippetBuilder: StepDefinitionSnippetBuilder\n stream: Writable\n cleanup: IFormatterCleanupFn\n supportCodeLibrary: ISupportCodeLibrary\n}\n\nexport default class Formatter {\n protected colorFns: IColorFns\n protected cwd: string\n protected eventDataCollector: EventDataCollector\n protected log: IFormatterLogFn\n protected snippetBuilder: StepDefinitionSnippetBuilder\n protected stream: Writable\n protected supportCodeLibrary: ISupportCodeLibrary\n protected printAttachments: boolean\n private readonly cleanup: IFormatterCleanupFn\n static readonly documentation: string\n\n constructor(options: IFormatterOptions) {\n this.colorFns = options.colorFns\n this.cwd = options.cwd\n this.eventDataCollector = options.eventDataCollector\n this.log = options.log\n this.snippetBuilder = options.snippetBuilder\n this.stream = options.stream\n this.supportCodeLibrary = options.supportCodeLibrary\n this.cleanup = options.cleanup\n this.printAttachments = valueOrDefault(\n options.parsedArgvOptions.printAttachments,\n true\n )\n }\n\n async finished(): Promise<void> {\n await this.cleanup()\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export * from './types';
2
+ export * from './plugin_manager';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./plugin_manager"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAuB;AACvB,mDAAgC","sourcesContent":["export * from './types'\nexport * from './plugin_manager'\n"]}
@@ -0,0 +1,13 @@
1
+ /// <reference types="node" />
2
+ import { Plugin, PluginEvents } from './types';
3
+ import { IRunEnvironment, IRunOptions } from '../api';
4
+ export declare class PluginManager {
5
+ private pluginFns;
6
+ private handlers;
7
+ private cleanupFns;
8
+ constructor(pluginFns: Plugin[]);
9
+ private register;
10
+ init(logger: Console, configuration: IRunOptions, environment: IRunEnvironment): Promise<void>;
11
+ emit<K extends keyof PluginEvents>(event: K, value: PluginEvents[K]): void;
12
+ cleanup(): Promise<void>;
13
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PluginManager = void 0;
4
+ class PluginManager {
5
+ constructor(pluginFns) {
6
+ this.pluginFns = pluginFns;
7
+ this.handlers = { message: [] };
8
+ this.cleanupFns = [];
9
+ }
10
+ async register(event, handler) {
11
+ this.handlers[event].push(handler);
12
+ }
13
+ async init(logger, configuration, environment) {
14
+ for (const pluginFn of this.pluginFns) {
15
+ const cleanupFn = await pluginFn({
16
+ on: this.register.bind(this),
17
+ logger,
18
+ configuration,
19
+ environment,
20
+ });
21
+ if (cleanupFn) {
22
+ this.cleanupFns.push(cleanupFn);
23
+ }
24
+ }
25
+ }
26
+ emit(event, value) {
27
+ this.handlers[event].forEach((handler) => handler(value));
28
+ }
29
+ async cleanup() {
30
+ for (const cleanupFn of this.cleanupFns) {
31
+ await cleanupFn();
32
+ }
33
+ }
34
+ }
35
+ exports.PluginManager = PluginManager;
36
+ //# sourceMappingURL=plugin_manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin_manager.js","sourceRoot":"","sources":["../../src/plugin/plugin_manager.ts"],"names":[],"mappings":";;;AAOA,MAAa,aAAa;IAIxB,YAAoB,SAAmB;QAAnB,cAAS,GAAT,SAAS,CAAU;QAH/B,aAAQ,GAAoB,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;QAC3C,eAAU,GAAoB,EAAE,CAAA;IAEE,CAAC;IAEnC,KAAK,CAAC,QAAQ,CACpB,KAAQ,EACR,OAAyC;QAEzC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,IAAI,CACR,MAAe,EACf,aAA0B,EAC1B,WAA4B;QAE5B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE;YACrC,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC;gBAC/B,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC5B,MAAM;gBACN,aAAa;gBACb,WAAW;aACZ,CAAC,CAAA;YACF,IAAI,SAAS,EAAE;gBACb,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;aAChC;SACF;IACH,CAAC;IAED,IAAI,CAA+B,KAAQ,EAAE,KAAsB;QACjE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;IAC3D,CAAC;IAED,KAAK,CAAC,OAAO;QACX,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE;YACvC,MAAM,SAAS,EAAE,CAAA;SAClB;IACH,CAAC;CACF;AAxCD,sCAwCC","sourcesContent":["import { Plugin, PluginCleanup, PluginEvents } from './types'\nimport { IRunEnvironment, IRunOptions } from '../api'\n\ntype HandlerRegistry = {\n [K in keyof PluginEvents]: Array<(value: PluginEvents[K]) => void>\n}\n\nexport class PluginManager {\n private handlers: HandlerRegistry = { message: [] }\n private cleanupFns: PluginCleanup[] = []\n\n constructor(private pluginFns: Plugin[]) {}\n\n private async register<K extends keyof PluginEvents>(\n event: K,\n handler: (value: PluginEvents[K]) => void\n ) {\n this.handlers[event].push(handler)\n }\n\n async init(\n logger: Console,\n configuration: IRunOptions,\n environment: IRunEnvironment\n ) {\n for (const pluginFn of this.pluginFns) {\n const cleanupFn = await pluginFn({\n on: this.register.bind(this),\n logger,\n configuration,\n environment,\n })\n if (cleanupFn) {\n this.cleanupFns.push(cleanupFn)\n }\n }\n }\n\n emit<K extends keyof PluginEvents>(event: K, value: PluginEvents[K]): void {\n this.handlers[event].forEach((handler) => handler(value))\n }\n\n async cleanup(): Promise<void> {\n for (const cleanupFn of this.cleanupFns) {\n await cleanupFn()\n }\n }\n}\n"]}
@@ -0,0 +1,14 @@
1
+ /// <reference types="node" />
2
+ import { IRunEnvironment, IRunOptions } from '../api';
3
+ import { Envelope } from '@cucumber/messages';
4
+ export interface PluginEvents {
5
+ message: Envelope;
6
+ }
7
+ export interface PluginContext {
8
+ on: <K extends keyof PluginEvents>(event: K, handler: (value: PluginEvents[K]) => void) => void;
9
+ logger: Console;
10
+ configuration: IRunOptions;
11
+ environment: IRunEnvironment;
12
+ }
13
+ export declare type PluginCleanup = () => any | void | Promise<any | void>;
14
+ export declare type Plugin = (context: PluginContext) => Promise<PluginCleanup | void>;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/plugin/types.ts"],"names":[],"mappings":"","sourcesContent":["import { IRunEnvironment, IRunOptions } from '../api'\nimport { Envelope } from '@cucumber/messages'\n\nexport interface PluginEvents {\n message: Envelope\n}\n\nexport interface PluginContext {\n on: <K extends keyof PluginEvents>(\n event: K,\n handler: (value: PluginEvents[K]) => void\n ) => void\n logger: Console\n configuration: IRunOptions\n environment: IRunEnvironment\n}\n\nexport type PluginCleanup = () => any | void | Promise<any | void>\n\nexport type Plugin = (context: PluginContext) => Promise<PluginCleanup | void>\n"]}
File without changes
File without changes
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http_stream.js","sourceRoot":"","sources":["../../src/publish/http_stream.ts"],"names":[],"mappings":";;;;;AAAA,mCAAsD;AACtD,8CAAqB;AACrB,4CAAmB;AACnB,gDAAuB;AACvB,kDAAyB;AACzB,oDAAgD;AAIhD;;;;;;;;;GASG;AACH,MAAqB,UAAW,SAAQ,kBAAS;IAI/C,YACmB,GAAW,EACX,MAAkB,EAClB,OAAiC;QAElD,KAAK,CAAC;YACJ,kBAAkB,EAAE,IAAI;SACzB,CAAC,CAAA;QANe,QAAG,GAAH,GAAG,CAAQ;QACX,WAAM,GAAN,MAAM,CAAY;QAClB,YAAO,GAAP,OAAO,CAA0B;IAKpD,CAAC;IAED,MAAM,CACJ,KAAU,EACV,QAAwB,EACxB,QAAsC;QAEtC,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;YAC/B,aAAG,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE;gBACzB,IAAI,IAAA,6BAAa,EAAC,GAAG,CAAC;oBAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAA;gBAC5C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;gBACxB,IAAI,CAAC,QAAQ,GAAG,YAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;gBAClD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;YAChD,CAAC,CAAC,CAAA;SACH;aAAM;YACL,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;SAC/C;IACH,CAAC;IAED,MAAM,CAAC,QAAwC;QAC7C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE;YACrB,IAAI,CAAC,eAAe,CAClB,IAAI,CAAC,GAAG,EACR,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,OAAO,EACZ,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;gBACb,IAAI,IAAA,6BAAa,EAAC,IAAI,CAAC;oBAAE,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAA;gBAC9C,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE;oBAC/B,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;oBACxD,IACE,IAAI,CAAC,UAAU,KAAK,GAAG;wBACvB,IAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,EACnC;wBACA,IAAI,CAAC,eAAe,CAClB,IAAI,CAAC,OAAO,CAAC,QAAQ,EACrB,KAAK,EACL,EAAE,EACF,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;4BACb,IAAI,IAAA,6BAAa,EAAC,IAAI,CAAC;gCAAE,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAA;4BAC9C,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;4BACxD,QAAQ,EAAE,CAAA;wBACZ,CAAC,CACF,CAAA;qBACF;yBAAM;wBACL,QAAQ,EAAE,CAAA;qBACX;gBACH,CAAC,CAAC,CAAA;YACJ,CAAC,CACF,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,gBAAgB,CAAC,GAAyB,EAAE,IAAgB;QAClE,IAAI,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC1B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YACvB,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;QACrC,CAAC,CAAC,CAAA;QACF,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACjB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;YACjC,IAAI,EAAE,CAAA;QACR,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,sBAAsB,CAC5B,GAAyB,EACzB,GAAW,EACX,MAAc;QAEd,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG;YACvB,IAAI,CAAC,IAAI,CACP,OAAO,EACP,IAAI,KAAK,CACP,0BAA0B,GAAG,CAAC,UAAU,SAAS,MAAM,IAAI,GAAG,EAAE,CACjE,CACF,CAAA;IACL,CAAC;IAEO,eAAe,CACrB,GAAW,EACX,MAAkB,EAClB,OAAiC,EACjC,QAAkE;QAElE,MAAM,KAAK,GAAG,IAAA,6BAAa,EAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,eAAK,CAAC,CAAC,CAAC,cAAI,CAAA;QAChE,MAAM,qBAAqB,GAA6B,EAAE,CAAA;QAE1D,MAAM,MAAM,GAAG,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM,CAAA;QACpD,IAAI,MAAM,EAAE;YACV,qBAAqB,CAAC,gBAAgB,CAAC,GAAG,YAAE,CAAC,QAAQ,CACnD,IAAI,CAAC,YAAY,CAClB,CAAC,IAAI,CAAA;SACP;QAED,MAAM,UAAU,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,qBAAqB,EAAE,CAAA;QAC3D,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;YAC7B,MAAM;YACN,OAAO,EAAE,UAAU;SACpB,CAAC,CAAA;QACF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;QACjD,GAAG,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;YACjD,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACrB,CAAC,CAAC,CAAA;QAEF,IAAI,MAAM,EAAE;YACV,IAAA,iBAAQ,EAAC,YAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC5D,IAAI,IAAA,6BAAa,EAAC,GAAG,CAAC,EAAE;oBACtB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;iBACxB;YACH,CAAC,CAAC,CAAA;SACH;aAAM;YACL,GAAG,CAAC,GAAG,EAAE,CAAA;SACV;IACH,CAAC;CACF;AA9HD,6BA8HC","sourcesContent":["import { pipeline, Transform, Writable } from 'stream'\nimport tmp from 'tmp'\nimport fs from 'fs'\nimport http from 'http'\nimport https from 'https'\nimport { doesHaveValue } from '../value_checker'\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT'\n\n/**\n * This Writable writes data to a HTTP/HTTPS URL.\n *\n * It has special handling for https://reports.cucumber.io/\n * which uses an API where the first request is a `GET`,\n * and if the response is 202 with a Location header, issues\n * a PUT request to that URL.\n *\n * 3xx redirects are not currently followed.\n */\nexport default class HttpStream extends Transform {\n private tempFilePath: string\n private tempFile: Writable\n\n constructor(\n private readonly url: string,\n private readonly method: HttpMethod,\n private readonly headers: http.OutgoingHttpHeaders\n ) {\n super({\n readableObjectMode: true,\n })\n }\n\n _write(\n chunk: any,\n encoding: BufferEncoding,\n callback: (err?: Error | null) => void\n ): void {\n if (this.tempFile === undefined) {\n tmp.file((err, name, fd) => {\n if (doesHaveValue(err)) return callback(err)\n this.tempFilePath = name\n this.tempFile = fs.createWriteStream(name, { fd })\n this.tempFile.write(chunk, encoding, callback)\n })\n } else {\n this.tempFile.write(chunk, encoding, callback)\n }\n }\n\n _final(callback: (error?: Error | null) => void): void {\n this.tempFile.end(() => {\n this.sendHttpRequest(\n this.url,\n this.method,\n this.headers,\n (err1, res1) => {\n if (doesHaveValue(err1)) return callback(err1)\n this.pushResponseBody(res1, () => {\n this.emitErrorUnlessHttp2xx(res1, this.url, this.method)\n if (\n res1.statusCode === 202 &&\n res1.headers.location !== undefined\n ) {\n this.sendHttpRequest(\n res1.headers.location,\n 'PUT',\n {},\n (err2, res2) => {\n if (doesHaveValue(err2)) return callback(err2)\n this.emitErrorUnlessHttp2xx(res2, this.url, this.method)\n callback()\n }\n )\n } else {\n callback()\n }\n })\n }\n )\n })\n }\n\n private pushResponseBody(res: http.IncomingMessage, done: () => void): void {\n let body = Buffer.alloc(0)\n res.on('data', (chunk) => {\n body = Buffer.concat([body, chunk])\n })\n res.on('end', () => {\n this.push(body.toString('utf-8'))\n done()\n })\n }\n\n private emitErrorUnlessHttp2xx(\n res: http.IncomingMessage,\n url: string,\n method: string\n ): void {\n if (res.statusCode >= 300)\n this.emit(\n 'error',\n new Error(\n `Unexpected http status ${res.statusCode} from ${method} ${url}`\n )\n )\n }\n\n private sendHttpRequest(\n url: string,\n method: HttpMethod,\n headers: http.OutgoingHttpHeaders,\n callback: (err?: Error | null, res?: http.IncomingMessage) => void\n ): void {\n const httpx = doesHaveValue(url.match(/^https:/)) ? https : http\n const additionalHttpHeaders: http.OutgoingHttpHeaders = {}\n\n const upload = method === 'PUT' || method === 'POST'\n if (upload) {\n additionalHttpHeaders['Content-Length'] = fs.statSync(\n this.tempFilePath\n ).size\n }\n\n const allHeaders = { ...headers, ...additionalHttpHeaders }\n const req = httpx.request(url, {\n method,\n headers: allHeaders,\n })\n req.on('error', (err) => this.emit('error', err))\n req.on('response', (res) => {\n res.on('error', (err) => this.emit('error', err))\n callback(null, res)\n })\n\n if (upload) {\n pipeline(fs.createReadStream(this.tempFilePath), req, (err) => {\n if (doesHaveValue(err)) {\n this.emit('error', err)\n }\n })\n } else {\n req.end()\n }\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import { publishPlugin } from './publish_plugin';
2
+ export default publishPlugin;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const publish_plugin_1 = require("./publish_plugin");
4
+ exports.default = publish_plugin_1.publishPlugin;
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/publish/index.ts"],"names":[],"mappings":";;AAAA,qDAAgD;AAEhD,kBAAe,8BAAa,CAAA","sourcesContent":["import { publishPlugin } from './publish_plugin'\n\nexport default publishPlugin\n"]}
@@ -0,0 +1,2 @@
1
+ import { Plugin } from '../plugin';
2
+ export declare const publishPlugin: Plugin;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.publishPlugin = void 0;
7
+ const http_stream_1 = __importDefault(require("./http_stream"));
8
+ const stream_1 = require("stream");
9
+ const supports_color_1 = require("supports-color");
10
+ const has_ansi_1 = __importDefault(require("has-ansi"));
11
+ const strip_ansi_1 = __importDefault(require("strip-ansi"));
12
+ const DEFAULT_CUCUMBER_PUBLISH_URL = 'https://messages.cucumber.io/api/reports';
13
+ const publishPlugin = async ({ on, logger, configuration, environment, }) => {
14
+ if (!configuration.formats.publish) {
15
+ return undefined;
16
+ }
17
+ const { url = DEFAULT_CUCUMBER_PUBLISH_URL, token } = configuration.formats.publish;
18
+ const headers = {};
19
+ if (token !== undefined) {
20
+ headers.Authorization = `Bearer ${token}`;
21
+ }
22
+ const stream = new http_stream_1.default(url, 'GET', headers);
23
+ const readerStream = new stream_1.Writable({
24
+ objectMode: true,
25
+ write: function (responseBody, encoding, writeCallback) {
26
+ environment.stderr.write(sanitisePublishOutput(responseBody, environment.stderr) + '\n');
27
+ writeCallback();
28
+ },
29
+ });
30
+ stream.pipe(readerStream);
31
+ stream.on('error', (error) => logger.error(error.message));
32
+ on('message', (value) => stream.write(JSON.stringify(value) + '\n'));
33
+ return () => stream.end();
34
+ };
35
+ exports.publishPlugin = publishPlugin;
36
+ /*
37
+ This is because the Cucumber Reports service returns a pre-formatted console message
38
+ including ANSI escapes, so if our stderr stream doesn't support those we need to
39
+ strip them back out. Ideally we should get structured data from the service and
40
+ compose the console message on this end.
41
+ */
42
+ function sanitisePublishOutput(raw, stderr) {
43
+ if (!(0, supports_color_1.supportsColor)(stderr) && (0, has_ansi_1.default)(raw)) {
44
+ return (0, strip_ansi_1.default)(raw);
45
+ }
46
+ return raw;
47
+ }
48
+ //# sourceMappingURL=publish_plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish_plugin.js","sourceRoot":"","sources":["../../src/publish/publish_plugin.ts"],"names":[],"mappings":";;;;;;AACA,gEAAsC;AACtC,mCAAiC;AACjC,mDAA8C;AAC9C,wDAA8B;AAC9B,4DAAkC;AAElC,MAAM,4BAA4B,GAAG,0CAA0C,CAAA;AAExE,MAAM,aAAa,GAAW,KAAK,EAAE,EAC1C,EAAE,EACF,MAAM,EACN,aAAa,EACb,WAAW,GACZ,EAAE,EAAE;IACH,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE;QAClC,OAAO,SAAS,CAAA;KACjB;IACD,MAAM,EAAE,GAAG,GAAG,4BAA4B,EAAE,KAAK,EAAE,GACjD,aAAa,CAAC,OAAO,CAAC,OAAO,CAAA;IAC/B,MAAM,OAAO,GAA8B,EAAE,CAAA;IAC7C,IAAI,KAAK,KAAK,SAAS,EAAE;QACvB,OAAO,CAAC,aAAa,GAAG,UAAU,KAAK,EAAE,CAAA;KAC1C;IACD,MAAM,MAAM,GAAG,IAAI,qBAAU,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;IAClD,MAAM,YAAY,GAAG,IAAI,iBAAQ,CAAC;QAChC,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,UAAU,YAAoB,EAAE,QAAQ,EAAE,aAAa;YAC5D,WAAW,CAAC,MAAM,CAAC,KAAK,CACtB,qBAAqB,CAAC,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAC/D,CAAA;YACD,aAAa,EAAE,CAAA;QACjB,CAAC;KACF,CAAC,CAAA;IACF,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IACzB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;IACjE,EAAE,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA;IACpE,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAA;AAC3B,CAAC,CAAA;AA7BY,QAAA,aAAa,iBA6BzB;AACD;;;;;GAKG;AACH,SAAS,qBAAqB,CAAC,GAAW,EAAE,MAAgB;IAC1D,IAAI,CAAC,IAAA,8BAAa,EAAC,MAAM,CAAC,IAAI,IAAA,kBAAO,EAAC,GAAG,CAAC,EAAE;QAC1C,OAAO,IAAA,oBAAS,EAAC,GAAG,CAAC,CAAA;KACtB;IACD,OAAO,GAAG,CAAA;AACZ,CAAC","sourcesContent":["import { Plugin } from '../plugin'\nimport HttpStream from './http_stream'\nimport { Writable } from 'stream'\nimport { supportsColor } from 'supports-color'\nimport hasAnsi from 'has-ansi'\nimport stripAnsi from 'strip-ansi'\n\nconst DEFAULT_CUCUMBER_PUBLISH_URL = 'https://messages.cucumber.io/api/reports'\n\nexport const publishPlugin: Plugin = async ({\n on,\n logger,\n configuration,\n environment,\n}) => {\n if (!configuration.formats.publish) {\n return undefined\n }\n const { url = DEFAULT_CUCUMBER_PUBLISH_URL, token } =\n configuration.formats.publish\n const headers: { [key: string]: string } = {}\n if (token !== undefined) {\n headers.Authorization = `Bearer ${token}`\n }\n const stream = new HttpStream(url, 'GET', headers)\n const readerStream = new Writable({\n objectMode: true,\n write: function (responseBody: string, encoding, writeCallback) {\n environment.stderr.write(\n sanitisePublishOutput(responseBody, environment.stderr) + '\\n'\n )\n writeCallback()\n },\n })\n stream.pipe(readerStream)\n stream.on('error', (error: Error) => logger.error(error.message))\n on('message', (value) => stream.write(JSON.stringify(value) + '\\n'))\n return () => stream.end()\n}\n/*\nThis is because the Cucumber Reports service returns a pre-formatted console message\nincluding ANSI escapes, so if our stderr stream doesn't support those we need to\nstrip them back out. Ideally we should get structured data from the service and\ncompose the console message on this end.\n */\nfunction sanitisePublishOutput(raw: string, stderr: Writable) {\n if (!supportsColor(stderr) && hasAnsi(raw)) {\n return stripAnsi(raw)\n }\n return raw\n}\n"]}
package/lib/time.d.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  import * as messages from '@cucumber/messages';
2
- declare const methods: any;
2
+ import { FakeClock, GlobalTimers, TimerId } from '@sinonjs/fake-timers';
3
+ interface IMethods extends GlobalTimers<TimerId> {
4
+ beginTiming: () => void;
5
+ endTiming: () => number;
6
+ performance: FakeClock<TimerId>['performance'];
7
+ }
8
+ declare const methods: Partial<IMethods>;
3
9
  export declare function durationBetweenTimestamps(startedTimestamp: messages.Timestamp, finishedTimestamp: messages.Timestamp): messages.Duration;
4
10
  export declare function wrapPromiseWithTimeout<T>(promise: Promise<T>, timeoutInMilliseconds: number, timeoutMessage?: string): Promise<T>;
5
11
  export default methods;
package/lib/time.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"time.js","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAwC;AACxC,6DAA8C;AAE9C,IAAI,iBAAyB,CAAA;AAE7B,MAAM,OAAO,GAAQ;IACnB,WAAW;QACT,iBAAiB,GAAG,YAAY,EAAE,CAAA;IACpC,CAAC;IACD,aAAa,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;IACzC,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;IACvC,IAAI;IACJ,SAAS;QACP,OAAO,YAAY,EAAE,GAAG,iBAAiB,CAAA;IAC3C,CAAC;IACD,WAAW,EAAE,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC;IACrC,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;IACnC,WAAW,EAAX,wBAAW;CACZ,CAAA;AAED,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE;IACvC,OAAO,CAAC,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAChD,OAAO,CAAC,cAAc,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;CACrD;AAED,SAAS,YAAY;IACnB,OAAO,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,CAAA;AAClC,CAAC;AAED,SAAgB,yBAAyB,CACvC,gBAAoC,EACpC,iBAAqC;IAErC,MAAM,cAAc,GAClB,QAAQ,CAAC,cAAc,CAAC,iCAAiC,CACvD,iBAAiB,CAClB;QACD,QAAQ,CAAC,cAAc,CAAC,iCAAiC,CAAC,gBAAgB,CAAC,CAAA;IAC7E,OAAO,QAAQ,CAAC,cAAc,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAA;AACvE,CAAC;AAVD,8DAUC;AAEM,KAAK,UAAU,sBAAsB,CAC1C,OAAmB,EACnB,qBAA6B,EAC7B,iBAAyB,EAAE;IAE3B,IAAI,SAAyB,CAAA;IAC7B,IAAI,cAAc,KAAK,EAAE,EAAE;QACzB,cAAc,GAAG,kCAAkC,qBAAqB,eAAe,CAAA;KACxF;IACD,MAAM,cAAc,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxD,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE;YAClC,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAA;QACnC,CAAC,EAAE,qBAAqB,CAAC,CAAA;IAC3B,CAAC,CAAC,CAAA;IACF,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAChE,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAChC,CAAA;AACH,CAAC;AAjBD,wDAiBC;AAED,kBAAe,OAAO,CAAA","sourcesContent":["import { performance } from 'perf_hooks'\nimport * as messages from '@cucumber/messages'\n\nlet previousTimestamp: number\n\nconst methods: any = {\n beginTiming() {\n previousTimestamp = getTimestamp()\n },\n clearInterval: clearInterval.bind(global),\n clearTimeout: clearTimeout.bind(global),\n Date,\n endTiming() {\n return getTimestamp() - previousTimestamp\n },\n setInterval: setInterval.bind(global),\n setTimeout: setTimeout.bind(global),\n performance,\n}\n\nif (typeof setImmediate !== 'undefined') {\n methods.setImmediate = setImmediate.bind(global)\n methods.clearImmediate = clearImmediate.bind(global)\n}\n\nfunction getTimestamp(): number {\n return methods.performance.now()\n}\n\nexport function durationBetweenTimestamps(\n startedTimestamp: messages.Timestamp,\n finishedTimestamp: messages.Timestamp\n): messages.Duration {\n const durationMillis =\n messages.TimeConversion.timestampToMillisecondsSinceEpoch(\n finishedTimestamp\n ) -\n messages.TimeConversion.timestampToMillisecondsSinceEpoch(startedTimestamp)\n return messages.TimeConversion.millisecondsToDuration(durationMillis)\n}\n\nexport async function wrapPromiseWithTimeout<T>(\n promise: Promise<T>,\n timeoutInMilliseconds: number,\n timeoutMessage: string = ''\n): Promise<T> {\n let timeoutId: NodeJS.Timeout\n if (timeoutMessage === '') {\n timeoutMessage = `Action did not complete within ${timeoutInMilliseconds} milliseconds`\n }\n const timeoutPromise = new Promise<T>((resolve, reject) => {\n timeoutId = methods.setTimeout(() => {\n reject(new Error(timeoutMessage))\n }, timeoutInMilliseconds)\n })\n return await Promise.race([promise, timeoutPromise]).finally(() =>\n methods.clearTimeout(timeoutId)\n )\n}\n\nexport default methods\n"]}
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAwC;AACxC,6DAA8C;AAG9C,IAAI,iBAAyB,CAAA;AAQ7B,MAAM,OAAO,GAAsB;IACjC,WAAW;QACT,iBAAiB,GAAG,YAAY,EAAE,CAAA;IACpC,CAAC;IACD,aAAa,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;IACzC,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;IACvC,IAAI;IACJ,SAAS;QACP,OAAO,YAAY,EAAE,GAAG,iBAAiB,CAAA;IAC3C,CAAC;IACD,WAAW,EAAE,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC;IACrC,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;IACnC,WAAW,EAAX,wBAAW;CACZ,CAAA;AAED,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE;IACvC,OAAO,CAAC,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAChD,OAAO,CAAC,cAAc,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;CACrD;AAED,SAAS,YAAY;IACnB,OAAO,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,CAAA;AAClC,CAAC;AAED,SAAgB,yBAAyB,CACvC,gBAAoC,EACpC,iBAAqC;IAErC,MAAM,cAAc,GAClB,QAAQ,CAAC,cAAc,CAAC,iCAAiC,CACvD,iBAAiB,CAClB;QACD,QAAQ,CAAC,cAAc,CAAC,iCAAiC,CAAC,gBAAgB,CAAC,CAAA;IAC7E,OAAO,QAAQ,CAAC,cAAc,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAA;AACvE,CAAC;AAVD,8DAUC;AAEM,KAAK,UAAU,sBAAsB,CAC1C,OAAmB,EACnB,qBAA6B,EAC7B,iBAAyB,EAAE;IAE3B,IAAI,SAAkB,CAAA;IACtB,IAAI,cAAc,KAAK,EAAE,EAAE;QACzB,cAAc,GAAG,kCAAkC,qBAAqB,eAAe,CAAA;KACxF;IACD,MAAM,cAAc,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxD,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE;YAClC,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAA;QACnC,CAAC,EAAE,qBAAqB,CAAC,CAAA;IAC3B,CAAC,CAAC,CAAA;IACF,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAChE,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAChC,CAAA;AACH,CAAC;AAjBD,wDAiBC;AAED,kBAAe,OAAO,CAAA","sourcesContent":["import { performance } from 'perf_hooks'\nimport * as messages from '@cucumber/messages'\nimport { FakeClock, GlobalTimers, TimerId } from '@sinonjs/fake-timers'\n\nlet previousTimestamp: number\n\ninterface IMethods extends GlobalTimers<TimerId> {\n beginTiming: () => void\n endTiming: () => number\n performance: FakeClock<TimerId>['performance']\n}\n\nconst methods: Partial<IMethods> = {\n beginTiming() {\n previousTimestamp = getTimestamp()\n },\n clearInterval: clearInterval.bind(global),\n clearTimeout: clearTimeout.bind(global),\n Date,\n endTiming() {\n return getTimestamp() - previousTimestamp\n },\n setInterval: setInterval.bind(global),\n setTimeout: setTimeout.bind(global),\n performance,\n}\n\nif (typeof setImmediate !== 'undefined') {\n methods.setImmediate = setImmediate.bind(global)\n methods.clearImmediate = clearImmediate.bind(global)\n}\n\nfunction getTimestamp(): number {\n return methods.performance.now()\n}\n\nexport function durationBetweenTimestamps(\n startedTimestamp: messages.Timestamp,\n finishedTimestamp: messages.Timestamp\n): messages.Duration {\n const durationMillis =\n messages.TimeConversion.timestampToMillisecondsSinceEpoch(\n finishedTimestamp\n ) -\n messages.TimeConversion.timestampToMillisecondsSinceEpoch(startedTimestamp)\n return messages.TimeConversion.millisecondsToDuration(durationMillis)\n}\n\nexport async function wrapPromiseWithTimeout<T>(\n promise: Promise<T>,\n timeoutInMilliseconds: number,\n timeoutMessage: string = ''\n): Promise<T> {\n let timeoutId: TimerId\n if (timeoutMessage === '') {\n timeoutMessage = `Action did not complete within ${timeoutInMilliseconds} milliseconds`\n }\n const timeoutPromise = new Promise<T>((resolve, reject) => {\n timeoutId = methods.setTimeout(() => {\n reject(new Error(timeoutMessage))\n }, timeoutInMilliseconds)\n })\n return await Promise.race([promise, timeoutPromise]).finally(() =>\n methods.clearTimeout(timeoutId)\n )\n}\n\nexport default methods\n"]}
package/lib/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "8.5.1";
1
+ export declare const version = "8.5.2";
package/lib/version.js CHANGED
@@ -2,5 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = void 0;
4
4
  // Generated by genversion.
5
- exports.version = '8.5.1';
5
+ exports.version = '8.5.2';
6
6
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;;AAAA,2BAA2B;AACd,QAAA,OAAO,GAAG,OAAO,CAAA","sourcesContent":["// Generated by genversion.\nexport const version = '8.5.1'\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;;AAAA,2BAA2B;AACd,QAAA,OAAO,GAAG,OAAO,CAAA","sourcesContent":["// Generated by genversion.\nexport const version = '8.5.2'\n"]}
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "gherkin",
9
9
  "tests"
10
10
  ],
11
- "version": "8.5.1",
11
+ "version": "8.5.2",
12
12
  "homepage": "https://github.com/cucumber/cucumber-js",
13
13
  "author": "Julien Biezemans <jb@jbpros.com>",
14
14
  "contributors": [
@@ -100,6 +100,7 @@
100
100
  "Łukasz Gandecki <lgandecki@css.edu>",
101
101
  "M.P. Korstanje <mpkorstanje@users.noreply.github.com>",
102
102
  "mannyluvstacos <mannyis@typingona.computer>",
103
+ "Manny Pamintuan <mannyis+still@typingona.computer>",
103
104
  "Marat Dyatko <vectart@gmail.com>",
104
105
  "Marc Burton <marc.burton@first-utility.com>",
105
106
  "Marcel Hoyer <mhoyer@pixelplastic.de>",
@@ -195,7 +196,7 @@
195
196
  },
196
197
  "dependencies": {
197
198
  "@cspotcode/source-map-support": "^0.8.0",
198
- "@cucumber/ci-environment": "9.0.4",
199
+ "@cucumber/ci-environment": "9.1.0",
199
200
  "@cucumber/cucumber-expressions": "16.0.0",
200
201
  "@cucumber/gherkin": "24.0.0",
201
202
  "@cucumber/gherkin-streams": "5.0.1",
@@ -236,8 +237,8 @@
236
237
  "devDependencies": {
237
238
  "@cucumber/compatibility-kit": "11.0.1",
238
239
  "@cucumber/query": "12.0.0",
239
- "@microsoft/api-documenter": "7.18.0",
240
- "@microsoft/api-extractor": "7.28.2",
240
+ "@microsoft/api-documenter": "7.19.1",
241
+ "@microsoft/api-extractor": "7.28.7",
241
242
  "@sinonjs/fake-timers": "9.1.2",
242
243
  "@types/chai": "4.3.1",
243
244
  "@types/dirty-chai": "2.0.2",
@@ -248,24 +249,24 @@
248
249
  "@types/lodash.merge": "4.6.7",
249
250
  "@types/lodash.mergewith": "4.6.7",
250
251
  "@types/mocha": "9.1.1",
251
- "@types/mustache": "4.1.3",
252
+ "@types/mustache": "4.2.1",
252
253
  "@types/mz": "2.7.4",
253
- "@types/node": "16.11.42",
254
+ "@types/node": "16.11.47",
254
255
  "@types/progress": "2.0.5",
255
256
  "@types/semver": "7.3.10",
256
257
  "@types/sinon-chai": "3.2.8",
257
258
  "@types/sinonjs__fake-timers": "8.1.2",
258
259
  "@types/stream-buffers": "3.0.4",
259
260
  "@types/tmp": "0.2.3",
260
- "@types/verror": "1.10.5",
261
- "@typescript-eslint/eslint-plugin": "5.30.3",
262
- "@typescript-eslint/parser": "5.30.3",
261
+ "@types/verror": "1.10.6",
262
+ "@typescript-eslint/eslint-plugin": "5.32.0",
263
+ "@typescript-eslint/parser": "5.32.0",
263
264
  "chai": "4.3.6",
264
265
  "chai-exclude": "2.1.0",
265
266
  "coffeescript": "2.7.0",
266
267
  "dependency-lint": "7.1.0",
267
268
  "dirty-chai": "2.0.1",
268
- "eslint": "8.18.0",
269
+ "eslint": "8.21.0",
269
270
  "eslint-config-prettier": "8.5.0",
270
271
  "eslint-plugin-import": "2.26.0",
271
272
  "eslint-plugin-node": "11.1.0",
@@ -284,10 +285,13 @@
284
285
  "sinon-chai": "3.7.0",
285
286
  "stream-buffers": "3.0.2",
286
287
  "stream-to-string": "1.2.0",
287
- "ts-node": "10.8.1",
288
+ "ts-node": "10.9.1",
288
289
  "tsd": "0.22.0",
289
290
  "typescript": "4.7.4"
290
291
  },
292
+ "overrides": {
293
+ "ansi-regex": "^5.0.1"
294
+ },
291
295
  "scripts": {
292
296
  "build-local": "genversion --es6 src/version.ts && tsc --build tsconfig.node.json && shx cp src/importer.js lib/ && shx cp src/wrapper.mjs lib/ && shx cp src/api/wrapper.mjs lib/api/",
293
297
  "cck-test": "mocha 'compatibility/**/*_spec.ts'",
@@ -1 +0,0 @@
1
- {"version":3,"file":"http_stream.js","sourceRoot":"","sources":["../../src/formatter/http_stream.ts"],"names":[],"mappings":";;;;;AAAA,mCAAsD;AACtD,8CAAqB;AACrB,4CAAmB;AACnB,gDAAuB;AACvB,kDAAyB;AACzB,oDAAgD;AAIhD;;;;;;;;;GASG;AACH,MAAqB,UAAW,SAAQ,kBAAS;IAI/C,YACmB,GAAW,EACX,MAAkB,EAClB,OAAiC;QAElD,KAAK,CAAC;YACJ,kBAAkB,EAAE,IAAI;SACzB,CAAC,CAAA;QANe,QAAG,GAAH,GAAG,CAAQ;QACX,WAAM,GAAN,MAAM,CAAY;QAClB,YAAO,GAAP,OAAO,CAA0B;IAKpD,CAAC;IAED,MAAM,CACJ,KAAU,EACV,QAAwB,EACxB,QAAsC;QAEtC,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;YAC/B,aAAG,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE;gBACzB,IAAI,IAAA,6BAAa,EAAC,GAAG,CAAC;oBAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAA;gBAC5C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;gBACxB,IAAI,CAAC,QAAQ,GAAG,YAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;gBAClD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;YAChD,CAAC,CAAC,CAAA;SACH;aAAM;YACL,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;SAC/C;IACH,CAAC;IAED,MAAM,CAAC,QAAwC;QAC7C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE;YACrB,IAAI,CAAC,eAAe,CAClB,IAAI,CAAC,GAAG,EACR,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,OAAO,EACZ,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;gBACb,IAAI,IAAA,6BAAa,EAAC,IAAI,CAAC;oBAAE,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAA;gBAC9C,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE;oBAC/B,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;oBACxD,IACE,IAAI,CAAC,UAAU,KAAK,GAAG;wBACvB,IAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,EACnC;wBACA,IAAI,CAAC,eAAe,CAClB,IAAI,CAAC,OAAO,CAAC,QAAQ,EACrB,KAAK,EACL,EAAE,EACF,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;4BACb,IAAI,IAAA,6BAAa,EAAC,IAAI,CAAC;gCAAE,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAA;4BAC9C,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;4BACxD,QAAQ,EAAE,CAAA;wBACZ,CAAC,CACF,CAAA;qBACF;yBAAM;wBACL,QAAQ,EAAE,CAAA;qBACX;gBACH,CAAC,CAAC,CAAA;YACJ,CAAC,CACF,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,gBAAgB,CAAC,GAAyB,EAAE,IAAgB;QAClE,IAAI,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC1B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YACvB,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;QACrC,CAAC,CAAC,CAAA;QACF,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACjB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;YACjC,IAAI,EAAE,CAAA;QACR,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,sBAAsB,CAC5B,GAAyB,EACzB,GAAW,EACX,MAAc;QAEd,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG;YACvB,IAAI,CAAC,IAAI,CACP,OAAO,EACP,IAAI,KAAK,CACP,0BAA0B,GAAG,CAAC,UAAU,SAAS,MAAM,IAAI,GAAG,EAAE,CACjE,CACF,CAAA;IACL,CAAC;IAEO,eAAe,CACrB,GAAW,EACX,MAAkB,EAClB,OAAiC,EACjC,QAAkE;QAElE,MAAM,KAAK,GAAG,IAAA,6BAAa,EAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,eAAK,CAAC,CAAC,CAAC,cAAI,CAAA;QAChE,MAAM,qBAAqB,GAA6B,EAAE,CAAA;QAE1D,MAAM,MAAM,GAAG,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM,CAAA;QACpD,IAAI,MAAM,EAAE;YACV,qBAAqB,CAAC,gBAAgB,CAAC,GAAG,YAAE,CAAC,QAAQ,CACnD,IAAI,CAAC,YAAY,CAClB,CAAC,IAAI,CAAA;SACP;QAED,MAAM,UAAU,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,qBAAqB,EAAE,CAAA;QAC3D,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;YAC7B,MAAM;YACN,OAAO,EAAE,UAAU;SACpB,CAAC,CAAA;QACF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;QACjD,GAAG,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;YACjD,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACrB,CAAC,CAAC,CAAA;QAEF,IAAI,MAAM,EAAE;YACV,IAAA,iBAAQ,EAAC,YAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC5D,IAAI,IAAA,6BAAa,EAAC,GAAG,CAAC,EAAE;oBACtB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;iBACxB;YACH,CAAC,CAAC,CAAA;SACH;aAAM;YACL,GAAG,CAAC,GAAG,EAAE,CAAA;SACV;IACH,CAAC;CACF;AA9HD,6BA8HC","sourcesContent":["import { pipeline, Transform, Writable } from 'stream'\nimport tmp from 'tmp'\nimport fs from 'fs'\nimport http from 'http'\nimport https from 'https'\nimport { doesHaveValue } from '../value_checker'\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT'\n\n/**\n * This Writable writes data to a HTTP/HTTPS URL.\n *\n * It has special handling for https://reports.cucumber.io/\n * which uses an API where the first request is a `GET`,\n * and if the response is 202 with a Location header, issues\n * a PUT request to that URL.\n *\n * 3xx redirects are not currently followed.\n */\nexport default class HttpStream extends Transform {\n private tempFilePath: string\n private tempFile: Writable\n\n constructor(\n private readonly url: string,\n private readonly method: HttpMethod,\n private readonly headers: http.OutgoingHttpHeaders\n ) {\n super({\n readableObjectMode: true,\n })\n }\n\n _write(\n chunk: any,\n encoding: BufferEncoding,\n callback: (err?: Error | null) => void\n ): void {\n if (this.tempFile === undefined) {\n tmp.file((err, name, fd) => {\n if (doesHaveValue(err)) return callback(err)\n this.tempFilePath = name\n this.tempFile = fs.createWriteStream(name, { fd })\n this.tempFile.write(chunk, encoding, callback)\n })\n } else {\n this.tempFile.write(chunk, encoding, callback)\n }\n }\n\n _final(callback: (error?: Error | null) => void): void {\n this.tempFile.end(() => {\n this.sendHttpRequest(\n this.url,\n this.method,\n this.headers,\n (err1, res1) => {\n if (doesHaveValue(err1)) return callback(err1)\n this.pushResponseBody(res1, () => {\n this.emitErrorUnlessHttp2xx(res1, this.url, this.method)\n if (\n res1.statusCode === 202 &&\n res1.headers.location !== undefined\n ) {\n this.sendHttpRequest(\n res1.headers.location,\n 'PUT',\n {},\n (err2, res2) => {\n if (doesHaveValue(err2)) return callback(err2)\n this.emitErrorUnlessHttp2xx(res2, this.url, this.method)\n callback()\n }\n )\n } else {\n callback()\n }\n })\n }\n )\n })\n }\n\n private pushResponseBody(res: http.IncomingMessage, done: () => void): void {\n let body = Buffer.alloc(0)\n res.on('data', (chunk) => {\n body = Buffer.concat([body, chunk])\n })\n res.on('end', () => {\n this.push(body.toString('utf-8'))\n done()\n })\n }\n\n private emitErrorUnlessHttp2xx(\n res: http.IncomingMessage,\n url: string,\n method: string\n ): void {\n if (res.statusCode >= 300)\n this.emit(\n 'error',\n new Error(\n `Unexpected http status ${res.statusCode} from ${method} ${url}`\n )\n )\n }\n\n private sendHttpRequest(\n url: string,\n method: HttpMethod,\n headers: http.OutgoingHttpHeaders,\n callback: (err?: Error | null, res?: http.IncomingMessage) => void\n ): void {\n const httpx = doesHaveValue(url.match(/^https:/)) ? https : http\n const additionalHttpHeaders: http.OutgoingHttpHeaders = {}\n\n const upload = method === 'PUT' || method === 'POST'\n if (upload) {\n additionalHttpHeaders['Content-Length'] = fs.statSync(\n this.tempFilePath\n ).size\n }\n\n const allHeaders = { ...headers, ...additionalHttpHeaders }\n const req = httpx.request(url, {\n method,\n headers: allHeaders,\n })\n req.on('error', (err) => this.emit('error', err))\n req.on('response', (res) => {\n res.on('error', (err) => this.emit('error', err))\n callback(null, res)\n })\n\n if (upload) {\n pipeline(fs.createReadStream(this.tempFilePath), req, (err) => {\n if (doesHaveValue(err)) {\n this.emit('error', err)\n }\n })\n } else {\n req.end()\n }\n }\n}\n"]}
@@ -1 +0,0 @@
1
- export declare const DEFAULT_CUCUMBER_PUBLISH_URL = "https://messages.cucumber.io/api/reports";
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_CUCUMBER_PUBLISH_URL = void 0;
4
- exports.DEFAULT_CUCUMBER_PUBLISH_URL = 'https://messages.cucumber.io/api/reports';
5
- //# sourceMappingURL=publish.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/formatter/publish.ts"],"names":[],"mappings":";;;AAAa,QAAA,4BAA4B,GACvC,0CAA0C,CAAA","sourcesContent":["export const DEFAULT_CUCUMBER_PUBLISH_URL =\n 'https://messages.cucumber.io/api/reports'\n"]}