@cucumber/cucumber 12.8.3 → 12.9.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/lib/api/plugins.js +6 -5
- package/lib/api/plugins.js.map +1 -1
- package/lib/configuration/check_schema.js +2 -0
- package/lib/configuration/check_schema.js.map +1 -1
- package/lib/filter/filter_plugin.d.ts +2 -2
- package/lib/filter/filter_plugin.js.map +1 -1
- package/lib/plugin/plugin_manager.d.ts +4 -1
- package/lib/plugin/plugin_manager.js +32 -21
- package/lib/plugin/plugin_manager.js.map +1 -1
- package/lib/plugin/types.d.ts +17 -1
- package/lib/plugin/types.js.map +1 -1
- package/lib/publish/publish_plugin.d.ts +2 -2
- package/lib/publish/publish_plugin.js +18 -12
- package/lib/publish/publish_plugin.js.map +1 -1
- package/lib/sharding/sharding_plugin.d.ts +2 -2
- package/lib/sharding/sharding_plugin.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +1 -1
package/lib/api/plugins.js
CHANGED
|
@@ -57,7 +57,7 @@ async function loadPlugin(specifier, cwd) {
|
|
|
57
57
|
async function initializeForLoadSources(coordinates, environment) {
|
|
58
58
|
// eventually we'll load plugin packages here
|
|
59
59
|
const pluginManager = new plugin_1.PluginManager(environment);
|
|
60
|
-
await pluginManager.
|
|
60
|
+
await pluginManager.initCoordinatorInternal('loadSources', filter_1.default, coordinates);
|
|
61
61
|
return pluginManager;
|
|
62
62
|
}
|
|
63
63
|
async function initializeForLoadSupport(environment) {
|
|
@@ -66,15 +66,16 @@ async function initializeForLoadSupport(environment) {
|
|
|
66
66
|
}
|
|
67
67
|
async function initializeForRunCucumber(configuration, environment) {
|
|
68
68
|
const pluginManager = new plugin_1.PluginManager(environment);
|
|
69
|
-
await pluginManager.
|
|
70
|
-
await pluginManager.
|
|
71
|
-
await pluginManager.initCoordinator('runCucumber', sharding_1.default, configuration.sources);
|
|
69
|
+
await pluginManager.initCoordinatorInternal('runCucumber', filter_1.default, configuration.sources);
|
|
70
|
+
await pluginManager.initCoordinatorInternal('runCucumber', sharding_1.default, configuration.sources);
|
|
72
71
|
if (configuration.plugins) {
|
|
73
72
|
for (const specifier of configuration.plugins.specifiers) {
|
|
74
73
|
const plugin = await loadPlugin(specifier, environment.cwd);
|
|
75
|
-
await pluginManager.
|
|
74
|
+
await pluginManager.initCoordinatorExternal('runCucumber', plugin, configuration.plugins.options, specifier);
|
|
76
75
|
}
|
|
77
76
|
}
|
|
77
|
+
// internal plugins that `emit` go last so consumers have a chance to `on`
|
|
78
|
+
await pluginManager.initCoordinatorInternal('runCucumber', publish_1.default, configuration.formats.publish);
|
|
78
79
|
return pluginManager;
|
|
79
80
|
}
|
|
80
81
|
//# sourceMappingURL=plugins.js.map
|
package/lib/api/plugins.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../src/api/plugins.ts"],"names":[],"mappings":";;;;;AAqDA,
|
|
1
|
+
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../src/api/plugins.ts"],"names":[],"mappings":"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","sourcesContent":["import { pathToFileURL } from 'node:url'\nimport path from 'node:path'\nimport { UsableEnvironment } from '../environment'\nimport filterPlugin from '../filter'\nimport { PluginManager, Plugin } from '../plugin'\nimport publishPlugin from '../publish'\nimport shardingPlugin from '../sharding'\nimport { doesNotHaveValue } from '../value_checker'\nimport { IRunConfiguration, ISourcesCoordinates } from './types'\n\nasync function importPlugin(specifier: string, cwd: string): Promise<any> {\n try {\n let normalized: URL | string = specifier\n if (specifier.startsWith('.')) {\n normalized = pathToFileURL(path.resolve(cwd, specifier))\n } else if (specifier.startsWith('file://')) {\n normalized = new URL(specifier)\n }\n return await import(normalized.toString())\n } catch (e) {\n throw new Error(`Failed to import plugin ${specifier}`, {\n cause: e,\n })\n }\n}\n\nfunction findPlugin(imported: any): Plugin | null {\n return findPluginRecursive(imported, 3)\n}\n\nfunction findPluginRecursive(thing: any, depth: number): Plugin | null {\n if (doesNotHaveValue(thing)) {\n return null\n }\n if (typeof thing === 'object' && thing.type === 'plugin') {\n return thing\n }\n depth--\n if (depth > 0) {\n return findPluginRecursive(thing.default, depth)\n }\n return null\n}\n\nasync function loadPlugin(specifier: string, cwd: string): Promise<Plugin> {\n const imported = await importPlugin(specifier, cwd)\n const found = findPlugin(imported)\n if (!found) {\n throw new Error(`${specifier} does not export a plugin`)\n }\n return found\n}\n\nexport async function initializeForLoadSources(\n coordinates: ISourcesCoordinates,\n environment: UsableEnvironment\n): Promise<PluginManager> {\n // eventually we'll load plugin packages here\n const pluginManager = new PluginManager(environment)\n await pluginManager.initCoordinatorInternal(\n 'loadSources',\n filterPlugin,\n coordinates\n )\n return pluginManager\n}\n\nexport async function initializeForLoadSupport(\n environment: UsableEnvironment\n): Promise<PluginManager> {\n // eventually we'll load plugin packages here\n return new PluginManager(environment)\n}\n\nexport async function initializeForRunCucumber(\n configuration: IRunConfiguration,\n environment: UsableEnvironment\n): Promise<PluginManager> {\n const pluginManager = new PluginManager(environment)\n\n await pluginManager.initCoordinatorInternal(\n 'runCucumber',\n filterPlugin,\n configuration.sources\n )\n await pluginManager.initCoordinatorInternal(\n 'runCucumber',\n shardingPlugin,\n configuration.sources\n )\n\n if (configuration.plugins) {\n for (const specifier of configuration.plugins.specifiers) {\n const plugin = await loadPlugin(specifier, environment.cwd)\n await pluginManager.initCoordinatorExternal(\n 'runCucumber',\n plugin,\n configuration.plugins.options,\n specifier\n )\n }\n }\n\n // internal plugins that `emit` go last so consumers have a chance to `on`\n await pluginManager.initCoordinatorInternal(\n 'runCucumber',\n publishPlugin,\n configuration.formats.publish\n )\n\n return pluginManager\n}\n"]}
|
|
@@ -53,6 +53,8 @@ const schema = yup.object().shape({
|
|
|
53
53
|
order: yup.string().matches(/^random:.*|random|defined$/),
|
|
54
54
|
paths: yup.array().of(yup.string()),
|
|
55
55
|
parallel: yup.number().integer().min(0),
|
|
56
|
+
plugin: yup.array().of(yup.string().trim().required()),
|
|
57
|
+
pluginOptions: yup.object(),
|
|
56
58
|
publish: yup.boolean(),
|
|
57
59
|
require: yup.array().of(yup.string()),
|
|
58
60
|
requireModule: yup.array().of(yup.string()),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check_schema.js","sourceRoot":"","sources":["../../src/configuration/check_schema.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"check_schema.js","sourceRoot":"","sources":["../../src/configuration/check_schema.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,kCAMC;AA3CD,yCAA0B;AAC1B,+CAA4C;AAG5C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC;IAChC,SAAS,EAAE,GAAG,CAAC,OAAO,EAAE;IACxB,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE;IACrB,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE;IACnB,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE;IACvB,MAAM,EAAE,GAAG;SACR,KAAK,EAAE;SACP,EAAE,CACD,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CACf,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAChB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5C,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CACjB,CACF;IACH,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE;IAC3B,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IACpC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAQ,CAAC,CAAC;IACnD,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IAClC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,4BAA4B,CAAC;IACzD,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IACnC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvC,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;IACtD,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE;IAC3B,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;IACtB,OAAO,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IACrC,aAAa,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IAC3C,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE;IAC5B,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE;IACrB,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE;IAClB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE;CAC9B,CAAC,CAAA;AAEF,SAAgB,WAAW,CAAC,aAAkB;IAC5C,OAAO,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE;QACxC,UAAU,EAAE,KAAK;QACjB,MAAM,EAAE,IAAI;QACZ,YAAY,EAAE,IAAI;KACnB,CAA4B,CAAA;AAC/B,CAAC","sourcesContent":["import * as yup from 'yup'\nimport { dialects } from '@cucumber/gherkin'\nimport { IConfiguration } from './types'\n\nconst schema = yup.object().shape({\n backtrace: yup.boolean(),\n dryRun: yup.boolean(),\n exit: yup.boolean(),\n failFast: yup.boolean(),\n format: yup\n .array()\n .of(\n yup.lazy((val) =>\n Array.isArray(val)\n ? yup.array().of(yup.string()).min(1).max(2)\n : yup.string()\n )\n ),\n formatOptions: yup.object(),\n import: yup.array().of(yup.string()),\n language: yup.string().oneOf(Object.keys(dialects)),\n name: yup.array().of(yup.string()),\n order: yup.string().matches(/^random:.*|random|defined$/),\n paths: yup.array().of(yup.string()),\n parallel: yup.number().integer().min(0),\n plugin: yup.array().of(yup.string().trim().required()),\n pluginOptions: yup.object(),\n publish: yup.boolean(),\n require: yup.array().of(yup.string()),\n requireModule: yup.array().of(yup.string()),\n retry: yup.number().integer().min(0),\n retryTagFilter: yup.string(),\n strict: yup.boolean(),\n tags: yup.string(),\n worldParameters: yup.object(),\n})\n\nexport function checkSchema(configuration: any): Partial<IConfiguration> {\n return schema.validateSync(configuration, {\n abortEarly: false,\n strict: true,\n stripUnknown: true,\n }) as Partial<IConfiguration>\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const filterPlugin:
|
|
1
|
+
import { InternalPlugin } from '../plugin';
|
|
2
|
+
export declare const filterPlugin: InternalPlugin;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter_plugin.js","sourceRoot":"","sources":["../../src/filter/filter_plugin.ts"],"names":[],"mappings":";;;;;;AACA,qEAA2C;AAC3C,mDAA8C;AAEjC,QAAA,YAAY,
|
|
1
|
+
{"version":3,"file":"filter_plugin.js","sourceRoot":"","sources":["../../src/filter/filter_plugin.ts"],"names":[],"mappings":";;;;;;AACA,qEAA2C;AAC3C,mDAA8C;AAEjC,QAAA,YAAY,GAAmB;IAC1C,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE;QACrE,IAAI,qBAAqB,GAAa,EAAE,CAAA;QACxC,EAAE,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;YAC5B,qBAAqB,GAAG,KAAK,CAAC,qBAAqB,CAAA;QACrD,CAAC,CAAC,CAAA;QAEF,SAAS,CAAC,gBAAgB,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;YAC/C,MAAM,YAAY,GAAG,IAAI,uBAAY,CAAC;gBACpC,GAAG,EAAE,WAAW,CAAC,GAAG;gBACpB,YAAY,EAAE,qBAAqB;gBACnC,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,aAAa,EAAE,OAAO,CAAC,aAAa;aACrC,CAAC,CAAA;YAEF,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;QACpE,CAAC,CAAC,CAAA;QAEF,SAAS,CAAC,eAAe,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE;YACpD,MAAM,cAAc,GAAG,CAAC,GAAG,gBAAgB,CAAC,CAAA;YAC5C,IAAA,4BAAY,EAAC,cAAc,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;YACnD,OAAO,cAAc,CAAA;QACvB,CAAC,CAAC,CAAA;IACJ,CAAC;CACF,CAAA","sourcesContent":["import { InternalPlugin } from '../plugin'\nimport PickleFilter from '../pickle_filter'\nimport { orderPickles } from './order_pickles'\n\nexport const filterPlugin: InternalPlugin = {\n type: 'plugin',\n coordinator: async ({ on, transform, options, logger, environment }) => {\n let unexpandedSourcePaths: string[] = []\n on('paths:resolve', (paths) => {\n unexpandedSourcePaths = paths.unexpandedSourcePaths\n })\n\n transform('pickles:filter', async (allPickles) => {\n const pickleFilter = new PickleFilter({\n cwd: environment.cwd,\n featurePaths: unexpandedSourcePaths,\n names: options.names,\n tagExpression: options.tagExpression,\n })\n\n return allPickles.filter((pickle) => pickleFilter.matches(pickle))\n })\n\n transform('pickles:order', async (unorderedPickles) => {\n const orderedPickles = [...unorderedPickles]\n orderPickles(orderedPickles, options.order, logger)\n return orderedPickles\n })\n },\n}\n"]}
|
|
@@ -9,7 +9,10 @@ export declare class PluginManager {
|
|
|
9
9
|
private registerHandler;
|
|
10
10
|
private registerTransformer;
|
|
11
11
|
initFormatter<OptionsType>(plugin: FormatterPlugin<OptionsType>, options: OptionsType, stream: NodeJS.WritableStream, write: (buffer: string | Uint8Array) => void, directory?: string, specifier?: string): Promise<void>;
|
|
12
|
-
|
|
12
|
+
initCoordinatorExternal<OptionsType>(operation: PluginOperation, plugin: Plugin<OptionsType>, options: OptionsType, specifier?: string): Promise<void>;
|
|
13
|
+
initCoordinatorInternal<OptionsType>(operation: PluginOperation, plugin: Plugin<OptionsType>, options: OptionsType): Promise<void>;
|
|
14
|
+
private initCoordinator;
|
|
15
|
+
private makeCoordinatorContext;
|
|
13
16
|
emit<K extends CoordinatorEventKey>(event: K, value: CoordinatorEventValues[K]): void;
|
|
14
17
|
transform<K extends CoordinatorTransformKey>(event: K, value: CoordinatorTransformValues[K]): Promise<CoordinatorTransformValues[K]>;
|
|
15
18
|
cleanup(): Promise<void>;
|
|
@@ -6,6 +6,7 @@ class PluginManager {
|
|
|
6
6
|
handlers = {
|
|
7
7
|
message: [],
|
|
8
8
|
'paths:resolve': [],
|
|
9
|
+
'publish:url': [],
|
|
9
10
|
};
|
|
10
11
|
transformers = {
|
|
11
12
|
'pickles:filter': [],
|
|
@@ -51,8 +52,28 @@ class PluginManager {
|
|
|
51
52
|
});
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
|
-
async
|
|
55
|
+
async initCoordinatorExternal(operation, plugin, options, specifier) {
|
|
56
|
+
const context = this.makeCoordinatorContext(operation, plugin, options, specifier);
|
|
57
|
+
await this.initCoordinator(plugin, context, specifier);
|
|
58
|
+
}
|
|
59
|
+
async initCoordinatorInternal(operation, plugin, options) {
|
|
55
60
|
const context = {
|
|
61
|
+
...this.makeCoordinatorContext(operation, plugin, options),
|
|
62
|
+
emit: this.emit.bind(this),
|
|
63
|
+
};
|
|
64
|
+
await this.initCoordinator(plugin, context);
|
|
65
|
+
}
|
|
66
|
+
async initCoordinator(plugin, context, specifier) {
|
|
67
|
+
const cleanupFn = await wrapErrorAsync(async () => await plugin.coordinator(context), `${formatCulprit(specifier)} errored when trying to init`);
|
|
68
|
+
if (typeof cleanupFn === 'function') {
|
|
69
|
+
this.cleanupFns.push({
|
|
70
|
+
cleanupFn: cleanupFn,
|
|
71
|
+
specifier,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
makeCoordinatorContext(operation, plugin, options, specifier) {
|
|
76
|
+
return {
|
|
56
77
|
operation,
|
|
57
78
|
on: (event, handler) => this.registerHandler(event, handler, specifier),
|
|
58
79
|
transform: (event, transformer) => this.registerTransformer(event, transformer, specifier),
|
|
@@ -66,23 +87,16 @@ class PluginManager {
|
|
|
66
87
|
env: { ...this.environment.env },
|
|
67
88
|
},
|
|
68
89
|
};
|
|
69
|
-
const cleanupFn = await wrapErrorAsync(async () => await plugin.coordinator(context), specifier, `Plugin "${specifier}" errored when trying to init`);
|
|
70
|
-
if (typeof cleanupFn === 'function') {
|
|
71
|
-
this.cleanupFns.push({
|
|
72
|
-
cleanupFn: cleanupFn,
|
|
73
|
-
specifier,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
90
|
}
|
|
77
91
|
emit(event, value) {
|
|
78
92
|
this.handlers[event].forEach(({ handler, specifier }) => {
|
|
79
|
-
wrapError(() => handler(value),
|
|
93
|
+
wrapError(() => handler(value), `${formatCulprit(specifier)} errored when trying to handle a "${event}" event`);
|
|
80
94
|
});
|
|
81
95
|
}
|
|
82
96
|
async transform(event, value) {
|
|
83
97
|
let transformed = value;
|
|
84
98
|
for (const { transformer, specifier } of this.transformers[event]) {
|
|
85
|
-
const returned = await wrapErrorAsync(async () => await transformer(transformed),
|
|
99
|
+
const returned = await wrapErrorAsync(async () => await transformer(transformed), `${formatCulprit(specifier)} errored when trying to do a "${event}" transform`);
|
|
86
100
|
if (typeof returned !== 'undefined') {
|
|
87
101
|
transformed = returned;
|
|
88
102
|
}
|
|
@@ -91,31 +105,28 @@ class PluginManager {
|
|
|
91
105
|
}
|
|
92
106
|
async cleanup() {
|
|
93
107
|
for (const { cleanupFn, specifier } of this.cleanupFns) {
|
|
94
|
-
await wrapErrorAsync(async () => await cleanupFn(),
|
|
108
|
+
await wrapErrorAsync(async () => await cleanupFn(), `${formatCulprit(specifier)} errored when trying to cleanup`);
|
|
95
109
|
}
|
|
96
110
|
}
|
|
97
111
|
}
|
|
98
112
|
exports.PluginManager = PluginManager;
|
|
99
|
-
function
|
|
113
|
+
function formatCulprit(specifier) {
|
|
114
|
+
return specifier ? `Plugin "${specifier}"` : 'Cucumber';
|
|
115
|
+
}
|
|
116
|
+
function wrapError(fn, message) {
|
|
100
117
|
try {
|
|
101
118
|
return fn();
|
|
102
119
|
}
|
|
103
120
|
catch (error) {
|
|
104
|
-
|
|
105
|
-
throw new Error(message, { cause: error });
|
|
106
|
-
}
|
|
107
|
-
throw error;
|
|
121
|
+
throw new Error(message, { cause: error });
|
|
108
122
|
}
|
|
109
123
|
}
|
|
110
|
-
async function wrapErrorAsync(fn,
|
|
124
|
+
async function wrapErrorAsync(fn, message) {
|
|
111
125
|
try {
|
|
112
126
|
return await fn();
|
|
113
127
|
}
|
|
114
128
|
catch (error) {
|
|
115
|
-
|
|
116
|
-
throw new Error(message, { cause: error });
|
|
117
|
-
}
|
|
118
|
-
throw error;
|
|
129
|
+
throw new Error(message, { cause: error });
|
|
119
130
|
}
|
|
120
131
|
}
|
|
121
132
|
//# sourceMappingURL=plugin_manager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin_manager.js","sourceRoot":"","sources":["../../src/plugin/plugin_manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { UsableEnvironment } from '../environment'\nimport {\n CoordinatorEventHandler,\n CoordinatorEventKey,\n CoordinatorEventValues,\n CoordinatorTransformer,\n CoordinatorTransformKey,\n CoordinatorTransformValues,\n FormatterPlugin,\n Plugin,\n PluginCleanup,\n PluginOperation,\n} from './types'\n\ntype SourcedEventHandler<K extends CoordinatorEventKey> = {\n handler: CoordinatorEventHandler<K>\n specifier?: string\n}\n\ntype SourcedTransformer<K extends CoordinatorTransformKey> = {\n transformer: CoordinatorTransformer<K>\n specifier?: string\n}\n\ntype SourcedCleanup = {\n cleanupFn: PluginCleanup\n specifier?: string\n}\n\ntype HandlerRegistry = {\n [K in CoordinatorEventKey]: Array<SourcedEventHandler<K>>\n}\n\ntype TransformerRegistry = {\n [K in CoordinatorTransformKey]: Array<SourcedTransformer<K>>\n}\n\nexport class PluginManager {\n private readonly handlers: HandlerRegistry = {\n message: [],\n 'paths:resolve': [],\n }\n private readonly transformers: TransformerRegistry = {\n 'pickles:filter': [],\n 'pickles:order': [],\n }\n private cleanupFns: SourcedCleanup[] = []\n\n constructor(private readonly environment: UsableEnvironment) {}\n\n private async registerHandler<K extends CoordinatorEventKey>(\n event: K,\n handler: CoordinatorEventHandler<K>,\n specifier?: string\n ) {\n if (!this.handlers[event]) {\n throw new Error(`Cannot register handler for unknown event \"${event}\"`)\n }\n this.handlers[event].push({\n handler,\n specifier,\n })\n }\n\n private async registerTransformer<K extends CoordinatorTransformKey>(\n event: K,\n transformer: CoordinatorTransformer<K>,\n specifier?: string\n ) {\n if (!this.transformers[event]) {\n throw new Error(\n `Cannot register transformer for unknown event \"${event}\"`\n )\n }\n this.transformers[event].push({\n transformer,\n specifier,\n })\n }\n\n async initFormatter<OptionsType>(\n plugin: FormatterPlugin<OptionsType>,\n options: OptionsType,\n stream: NodeJS.WritableStream,\n write: (buffer: string | Uint8Array) => void,\n directory?: string,\n specifier?: string\n ) {\n const cleanupFn = await plugin.formatter({\n on: (key, handler) => this.registerHandler(key, handler, specifier),\n options: plugin.optionsKey\n ? ((options as any)[plugin.optionsKey] ?? ({} as OptionsType))\n : options,\n logger: this.environment.logger,\n stream,\n write,\n directory,\n })\n if (typeof cleanupFn === 'function') {\n this.cleanupFns.push({\n cleanupFn: cleanupFn,\n specifier,\n })\n }\n }\n\n async initCoordinator<OptionsType>(\n operation: PluginOperation,\n plugin: Plugin<OptionsType>,\n options: OptionsType,\n specifier?: string\n ) {\n const context = {\n operation,\n on: <K extends CoordinatorEventKey>(\n event: K,\n handler: CoordinatorEventHandler<K>\n ) => this.registerHandler(event, handler, specifier),\n transform: <K extends CoordinatorTransformKey>(\n event: K,\n transformer: CoordinatorTransformer<K>\n ) => this.registerTransformer(event, transformer, specifier),\n options:\n 'optionsKey' in plugin && plugin.optionsKey\n ? ((options as any)[plugin.optionsKey] ?? ({} as OptionsType))\n : options,\n logger: this.environment.logger,\n environment: {\n cwd: this.environment.cwd,\n stderr: this.environment.stderr,\n env: { ...this.environment.env },\n },\n }\n const cleanupFn = await wrapErrorAsync(\n async () => await plugin.coordinator(context),\n specifier,\n `Plugin \"${specifier}\" errored when trying to init`\n )\n if (typeof cleanupFn === 'function') {\n this.cleanupFns.push({\n cleanupFn: cleanupFn,\n specifier,\n })\n }\n }\n\n emit<K extends CoordinatorEventKey>(\n event: K,\n value: CoordinatorEventValues[K]\n ): void {\n this.handlers[event].forEach(({ handler, specifier }) => {\n wrapError(\n () => handler(value),\n specifier,\n `Plugin \"${specifier}\" errored when trying to handle a \"${event}\" event`\n )\n })\n }\n\n async transform<K extends CoordinatorTransformKey>(\n event: K,\n value: CoordinatorTransformValues[K]\n ): Promise<CoordinatorTransformValues[K]> {\n let transformed = value\n for (const { transformer, specifier } of this.transformers[event]) {\n const returned = await wrapErrorAsync(\n async () => await transformer(transformed),\n specifier,\n `Plugin \"${specifier}\" errored when trying to do a \"${event}\" transform`\n )\n if (typeof returned !== 'undefined') {\n transformed = returned\n }\n }\n return transformed\n }\n\n async cleanup(): Promise<void> {\n for (const { cleanupFn, specifier } of this.cleanupFns) {\n await wrapErrorAsync(\n async () => await cleanupFn(),\n specifier,\n `Plugin \"${specifier}\" errored when trying to cleanup`\n )\n }\n }\n}\n\nfunction wrapError<T>(fn: () => T, specifier: string, message: string): T {\n try {\n return fn()\n } catch (error) {\n if (specifier) {\n throw new Error(message, { cause: error })\n }\n throw error\n }\n}\n\nasync function wrapErrorAsync<T>(\n fn: () => Promise<T>,\n specifier: string,\n message: string\n): Promise<T> {\n try {\n return await fn()\n } catch (error) {\n if (specifier) {\n throw new Error(message, { cause: error })\n }\n throw error\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"plugin_manager.js","sourceRoot":"","sources":["../../src/plugin/plugin_manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { UsableEnvironment } from '../environment'\nimport {\n CoordinatorContext,\n CoordinatorEventHandler,\n CoordinatorEventKey,\n CoordinatorEventValues,\n CoordinatorTransformer,\n CoordinatorTransformKey,\n CoordinatorTransformValues,\n FormatterPlugin,\n InternalPlugin,\n Plugin,\n PluginCleanup,\n PluginOperation,\n} from './types'\n\ntype SourcedEventHandler<K extends CoordinatorEventKey> = {\n handler: CoordinatorEventHandler<K>\n specifier?: string\n}\n\ntype SourcedTransformer<K extends CoordinatorTransformKey> = {\n transformer: CoordinatorTransformer<K>\n specifier?: string\n}\n\ntype SourcedCleanup = {\n cleanupFn: PluginCleanup\n specifier?: string\n}\n\ntype HandlerRegistry = {\n [K in CoordinatorEventKey]: Array<SourcedEventHandler<K>>\n}\n\ntype TransformerRegistry = {\n [K in CoordinatorTransformKey]: Array<SourcedTransformer<K>>\n}\n\nexport class PluginManager {\n private readonly handlers: HandlerRegistry = {\n message: [],\n 'paths:resolve': [],\n 'publish:url': [],\n }\n private readonly transformers: TransformerRegistry = {\n 'pickles:filter': [],\n 'pickles:order': [],\n }\n private cleanupFns: SourcedCleanup[] = []\n\n constructor(private readonly environment: UsableEnvironment) {}\n\n private async registerHandler<K extends CoordinatorEventKey>(\n event: K,\n handler: CoordinatorEventHandler<K>,\n specifier?: string\n ) {\n if (!this.handlers[event]) {\n throw new Error(`Cannot register handler for unknown event \"${event}\"`)\n }\n this.handlers[event].push({\n handler,\n specifier,\n })\n }\n\n private async registerTransformer<K extends CoordinatorTransformKey>(\n event: K,\n transformer: CoordinatorTransformer<K>,\n specifier?: string\n ) {\n if (!this.transformers[event]) {\n throw new Error(\n `Cannot register transformer for unknown event \"${event}\"`\n )\n }\n this.transformers[event].push({\n transformer,\n specifier,\n })\n }\n\n async initFormatter<OptionsType>(\n plugin: FormatterPlugin<OptionsType>,\n options: OptionsType,\n stream: NodeJS.WritableStream,\n write: (buffer: string | Uint8Array) => void,\n directory?: string,\n specifier?: string\n ) {\n const cleanupFn = await plugin.formatter({\n on: (key, handler) => this.registerHandler(key, handler, specifier),\n options: plugin.optionsKey\n ? ((options as any)[plugin.optionsKey] ?? ({} as OptionsType))\n : options,\n logger: this.environment.logger,\n stream,\n write,\n directory,\n })\n if (typeof cleanupFn === 'function') {\n this.cleanupFns.push({\n cleanupFn: cleanupFn,\n specifier,\n })\n }\n }\n\n async initCoordinatorExternal<OptionsType>(\n operation: PluginOperation,\n plugin: Plugin<OptionsType>,\n options: OptionsType,\n specifier?: string\n ) {\n const context = this.makeCoordinatorContext(\n operation,\n plugin,\n options,\n specifier\n )\n await this.initCoordinator(plugin, context, specifier)\n }\n\n async initCoordinatorInternal<OptionsType>(\n operation: PluginOperation,\n plugin: Plugin<OptionsType>,\n options: OptionsType\n ) {\n const context = {\n ...this.makeCoordinatorContext(operation, plugin, options),\n emit: this.emit.bind(this),\n }\n await this.initCoordinator(plugin, context)\n }\n\n private async initCoordinator<OptionsType>(\n plugin: Plugin<OptionsType>,\n context: CoordinatorContext<OptionsType>,\n specifier?: string\n ) {\n const cleanupFn = await wrapErrorAsync(\n async () => await plugin.coordinator(context),\n `${formatCulprit(specifier)} errored when trying to init`\n )\n if (typeof cleanupFn === 'function') {\n this.cleanupFns.push({\n cleanupFn: cleanupFn,\n specifier,\n })\n }\n }\n\n private makeCoordinatorContext<OptionsType>(\n operation: PluginOperation,\n plugin: Plugin<OptionsType> | InternalPlugin<OptionsType>,\n options: OptionsType,\n specifier?: string\n ) {\n return {\n operation,\n on: <K extends CoordinatorEventKey>(\n event: K,\n handler: CoordinatorEventHandler<K>\n ) => this.registerHandler(event, handler, specifier),\n transform: <K extends CoordinatorTransformKey>(\n event: K,\n transformer: CoordinatorTransformer<K>\n ) => this.registerTransformer(event, transformer, specifier),\n options:\n 'optionsKey' in plugin && plugin.optionsKey\n ? ((options as any)[plugin.optionsKey] ?? ({} as OptionsType))\n : options,\n logger: this.environment.logger,\n environment: {\n cwd: this.environment.cwd,\n stderr: this.environment.stderr,\n env: { ...this.environment.env },\n },\n }\n }\n\n emit<K extends CoordinatorEventKey>(\n event: K,\n value: CoordinatorEventValues[K]\n ): void {\n this.handlers[event].forEach(({ handler, specifier }) => {\n wrapError(\n () => handler(value),\n `${formatCulprit(specifier)} errored when trying to handle a \"${event}\" event`\n )\n })\n }\n\n async transform<K extends CoordinatorTransformKey>(\n event: K,\n value: CoordinatorTransformValues[K]\n ): Promise<CoordinatorTransformValues[K]> {\n let transformed = value\n for (const { transformer, specifier } of this.transformers[event]) {\n const returned = await wrapErrorAsync(\n async () => await transformer(transformed),\n `${formatCulprit(specifier)} errored when trying to do a \"${event}\" transform`\n )\n if (typeof returned !== 'undefined') {\n transformed = returned\n }\n }\n return transformed\n }\n\n async cleanup(): Promise<void> {\n for (const { cleanupFn, specifier } of this.cleanupFns) {\n await wrapErrorAsync(\n async () => await cleanupFn(),\n `${formatCulprit(specifier)} errored when trying to cleanup`\n )\n }\n }\n}\n\nfunction formatCulprit(specifier?: string) {\n return specifier ? `Plugin \"${specifier}\"` : 'Cucumber'\n}\n\nfunction wrapError<T>(fn: () => T, message: string): T {\n try {\n return fn()\n } catch (error) {\n throw new Error(message, { cause: error })\n }\n}\n\nasync function wrapErrorAsync<T>(\n fn: () => Promise<T>,\n message: string\n): Promise<T> {\n try {\n return await fn()\n } catch (error) {\n throw new Error(message, { cause: error })\n }\n}\n"]}
|
package/lib/plugin/types.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ export type CoordinatorEnvironment = {
|
|
|
35
35
|
* Keys for event handlers that plugins can register
|
|
36
36
|
* @public
|
|
37
37
|
*/
|
|
38
|
-
export type CoordinatorEventKey = 'message' | 'paths:resolve';
|
|
38
|
+
export type CoordinatorEventKey = 'message' | 'paths:resolve' | 'publish:url';
|
|
39
39
|
/**
|
|
40
40
|
* Keys for transforms that plugins can register
|
|
41
41
|
* @public
|
|
@@ -48,6 +48,7 @@ export type CoordinatorTransformKey = 'pickles:filter' | 'pickles:order';
|
|
|
48
48
|
export type CoordinatorEventValues = {
|
|
49
49
|
message: Readonly<Envelope>;
|
|
50
50
|
'paths:resolve': Readonly<IResolvedPaths>;
|
|
51
|
+
'publish:url': string;
|
|
51
52
|
};
|
|
52
53
|
/**
|
|
53
54
|
* Mapping of transform keys to their value types
|
|
@@ -125,6 +126,21 @@ export type Plugin<OptionsType = any> = {
|
|
|
125
126
|
*/
|
|
126
127
|
optionsKey?: string;
|
|
127
128
|
};
|
|
129
|
+
/**
|
|
130
|
+
* Context object passed to an internal plugin's coordinator function
|
|
131
|
+
* @internal
|
|
132
|
+
*/
|
|
133
|
+
export type InternalCoordinatorContext<OptionsType> = CoordinatorContext<OptionsType> & {
|
|
134
|
+
emit: <EventKey extends CoordinatorEventKey>(event: EventKey, value: CoordinatorEventValues[EventKey]) => void;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* A built-in plugin with the additional ability to emit events
|
|
138
|
+
* @internal
|
|
139
|
+
*/
|
|
140
|
+
export type InternalPlugin<OptionsType = any> = {
|
|
141
|
+
type: 'plugin';
|
|
142
|
+
coordinator: (context: InternalCoordinatorContext<OptionsType>) => PromiseLike<PluginCleanup | void> | PluginCleanup | void;
|
|
143
|
+
};
|
|
128
144
|
export type FormatterPluginContext<OptionsType> = {
|
|
129
145
|
on: (key: 'message', handler: (value: Envelope) => void) => void;
|
|
130
146
|
options: OptionsType;
|
package/lib/plugin/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/plugin/types.ts"],"names":[],"mappings":"","sourcesContent":["import { Writable } from 'node:stream'\nimport { Envelope } from '@cucumber/messages'\nimport { ILogger } from '../environment'\nimport { IFilterablePickle } from '../filter'\nimport { IResolvedPaths } from '../paths'\n\n/**\n * The operation Cucumber is doing in this process\n * @public\n * @remarks\n * `loadSources` and `loadSupport` are generally used as preflight operations\n * for complex use cases. `runCucumber` is the one where tests are actually\n * executed.\n */\nexport type PluginOperation = 'loadSources' | 'loadSupport' | 'runCucumber'\n\n/**\n * Subset of the environment available to plugins\n * @public\n */\nexport type CoordinatorEnvironment = {\n /**\n * Working directory for the project\n */\n cwd: string\n /**\n * Writable stream where the test run's warning/error output is written\n * and plugins can write to directly if required\n */\n stderr: Writable\n /**\n * Environment variables\n */\n env: Record<string, string | undefined>\n}\n\n/**\n * Keys for event handlers that plugins can register\n * @public\n */\nexport type CoordinatorEventKey = 'message' | 'paths:resolve'\n\n/**\n * Keys for transforms that plugins can register\n * @public\n */\nexport type CoordinatorTransformKey = 'pickles:filter' | 'pickles:order'\n\n/**\n * Mapping of event keys to their value types\n * @public\n */\nexport type CoordinatorEventValues = {\n message: Readonly<Envelope>\n 'paths:resolve': Readonly<IResolvedPaths>\n}\n\n/**\n * Mapping of transform keys to their value types\n * @public\n */\nexport type CoordinatorTransformValues = {\n 'pickles:filter': Readonly<Array<IFilterablePickle>>\n 'pickles:order': Readonly<Array<IFilterablePickle>>\n}\n\n/**\n * Handler function for a coordinator event\n * @public\n * @remarks\n * You can do async work here, but Cucumber will not await the Promise.\n */\nexport type CoordinatorEventHandler<K extends CoordinatorEventKey> = (\n value: CoordinatorEventValues[K]\n) => void\n\n/**\n * Transformer function for a coordinator transform\n * @remarks\n * Don't try to modify the original value. Return a transformed value, or\n * `undefined` to pass through unchanged.\n * @public\n */\nexport type CoordinatorTransformer<K extends CoordinatorTransformKey> = (\n value: CoordinatorTransformValues[K]\n) => PromiseLike<CoordinatorTransformValues[K]> | CoordinatorTransformValues[K]\n\n/**\n * Context object passed to a plugin's coordinator function\n * @public\n */\nexport type CoordinatorContext<OptionsType> = {\n /**\n * The operation Cucumber is doing in this process\n */\n operation: PluginOperation\n /**\n * Register an event handler\n */\n on: <EventKey extends CoordinatorEventKey>(\n event: EventKey,\n handler: CoordinatorEventHandler<EventKey>\n ) => void\n /**\n * Register a transformer\n */\n transform: <EventKey extends CoordinatorTransformKey>(\n event: EventKey,\n handler: CoordinatorTransformer<EventKey>\n ) => void\n /**\n * Options for the plugin\n */\n options: OptionsType\n /**\n * Logger for emitting user-facing messages or diagnostics\n */\n logger: ILogger\n /**\n * Subset of the environment\n */\n environment: CoordinatorEnvironment\n}\n\n/**\n * Optional cleanup function returned by a plugin coordinator\n * @public\n */\nexport type PluginCleanup = () => PromiseLike<void> | void\n\n/**\n * A plugin that can subscribe to events and register transforms\n * @public\n */\nexport type Plugin<OptionsType = any> = {\n type: 'plugin'\n /**\n * Coordinator function called during initialization\n * @remarks\n * Can do async work, and the Promise will be awaited. Can optionally return\n * a cleanup function to be called when Cucumber is about to exit.\n */\n coordinator: (\n context: CoordinatorContext<OptionsType>\n ) => PromiseLike<PluginCleanup | void> | PluginCleanup | void\n /**\n * Optional key to extract plugin-specific options from the root options object\n */\n optionsKey?: string\n}\n\nexport type FormatterPluginContext<OptionsType> = {\n on: (key: 'message', handler: (value: Envelope) => void) => void\n options: OptionsType\n logger: ILogger\n stream: NodeJS.WritableStream\n write: (buffer: string | Uint8Array) => void\n directory?: string\n}\n\nexport type FormatterPluginFunction<OptionsType> = (\n context: FormatterPluginContext<OptionsType>\n) => PromiseLike<PluginCleanup | void> | PluginCleanup | void\n\nexport type FormatterPlugin<OptionsType = any> = {\n type: 'formatter'\n formatter: FormatterPluginFunction<OptionsType>\n optionsKey?: string\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/plugin/types.ts"],"names":[],"mappings":"","sourcesContent":["import { Writable } from 'node:stream'\nimport { Envelope } from '@cucumber/messages'\nimport { ILogger } from '../environment'\nimport { IFilterablePickle } from '../filter'\nimport { IResolvedPaths } from '../paths'\n\n/**\n * The operation Cucumber is doing in this process\n * @public\n * @remarks\n * `loadSources` and `loadSupport` are generally used as preflight operations\n * for complex use cases. `runCucumber` is the one where tests are actually\n * executed.\n */\nexport type PluginOperation = 'loadSources' | 'loadSupport' | 'runCucumber'\n\n/**\n * Subset of the environment available to plugins\n * @public\n */\nexport type CoordinatorEnvironment = {\n /**\n * Working directory for the project\n */\n cwd: string\n /**\n * Writable stream where the test run's warning/error output is written\n * and plugins can write to directly if required\n */\n stderr: Writable\n /**\n * Environment variables\n */\n env: Record<string, string | undefined>\n}\n\n/**\n * Keys for event handlers that plugins can register\n * @public\n */\nexport type CoordinatorEventKey = 'message' | 'paths:resolve' | 'publish:url'\n\n/**\n * Keys for transforms that plugins can register\n * @public\n */\nexport type CoordinatorTransformKey = 'pickles:filter' | 'pickles:order'\n\n/**\n * Mapping of event keys to their value types\n * @public\n */\nexport type CoordinatorEventValues = {\n message: Readonly<Envelope>\n 'paths:resolve': Readonly<IResolvedPaths>\n 'publish:url': string\n}\n\n/**\n * Mapping of transform keys to their value types\n * @public\n */\nexport type CoordinatorTransformValues = {\n 'pickles:filter': Readonly<Array<IFilterablePickle>>\n 'pickles:order': Readonly<Array<IFilterablePickle>>\n}\n\n/**\n * Handler function for a coordinator event\n * @public\n * @remarks\n * You can do async work here, but Cucumber will not await the Promise.\n */\nexport type CoordinatorEventHandler<K extends CoordinatorEventKey> = (\n value: CoordinatorEventValues[K]\n) => void\n\n/**\n * Transformer function for a coordinator transform\n * @remarks\n * Don't try to modify the original value. Return a transformed value, or\n * `undefined` to pass through unchanged.\n * @public\n */\nexport type CoordinatorTransformer<K extends CoordinatorTransformKey> = (\n value: CoordinatorTransformValues[K]\n) => PromiseLike<CoordinatorTransformValues[K]> | CoordinatorTransformValues[K]\n\n/**\n * Context object passed to a plugin's coordinator function\n * @public\n */\nexport type CoordinatorContext<OptionsType> = {\n /**\n * The operation Cucumber is doing in this process\n */\n operation: PluginOperation\n /**\n * Register an event handler\n */\n on: <EventKey extends CoordinatorEventKey>(\n event: EventKey,\n handler: CoordinatorEventHandler<EventKey>\n ) => void\n /**\n * Register a transformer\n */\n transform: <EventKey extends CoordinatorTransformKey>(\n event: EventKey,\n handler: CoordinatorTransformer<EventKey>\n ) => void\n /**\n * Options for the plugin\n */\n options: OptionsType\n /**\n * Logger for emitting user-facing messages or diagnostics\n */\n logger: ILogger\n /**\n * Subset of the environment\n */\n environment: CoordinatorEnvironment\n}\n\n/**\n * Optional cleanup function returned by a plugin coordinator\n * @public\n */\nexport type PluginCleanup = () => PromiseLike<void> | void\n\n/**\n * A plugin that can subscribe to events and register transforms\n * @public\n */\nexport type Plugin<OptionsType = any> = {\n type: 'plugin'\n /**\n * Coordinator function called during initialization\n * @remarks\n * Can do async work, and the Promise will be awaited. Can optionally return\n * a cleanup function to be called when Cucumber is about to exit.\n */\n coordinator: (\n context: CoordinatorContext<OptionsType>\n ) => PromiseLike<PluginCleanup | void> | PluginCleanup | void\n /**\n * Optional key to extract plugin-specific options from the root options object\n */\n optionsKey?: string\n}\n\n/**\n * Context object passed to an internal plugin's coordinator function\n * @internal\n */\nexport type InternalCoordinatorContext<OptionsType> =\n CoordinatorContext<OptionsType> & {\n emit: <EventKey extends CoordinatorEventKey>(\n event: EventKey,\n value: CoordinatorEventValues[EventKey]\n ) => void\n }\n\n/**\n * A built-in plugin with the additional ability to emit events\n * @internal\n */\nexport type InternalPlugin<OptionsType = any> = {\n type: 'plugin'\n coordinator: (\n context: InternalCoordinatorContext<OptionsType>\n ) => PromiseLike<PluginCleanup | void> | PluginCleanup | void\n}\n\nexport type FormatterPluginContext<OptionsType> = {\n on: (key: 'message', handler: (value: Envelope) => void) => void\n options: OptionsType\n logger: ILogger\n stream: NodeJS.WritableStream\n write: (buffer: string | Uint8Array) => void\n directory?: string\n}\n\nexport type FormatterPluginFunction<OptionsType> = (\n context: FormatterPluginContext<OptionsType>\n) => PromiseLike<PluginCleanup | void> | PluginCleanup | void\n\nexport type FormatterPlugin<OptionsType = any> = {\n type: 'formatter'\n formatter: FormatterPluginFunction<OptionsType>\n optionsKey?: string\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const publishPlugin:
|
|
1
|
+
import { InternalPlugin } from '../plugin';
|
|
2
|
+
export declare const publishPlugin: InternalPlugin;
|
|
@@ -13,31 +13,36 @@ const node_fs_1 = require("node:fs");
|
|
|
13
13
|
const node_zlib_1 = require("node:zlib");
|
|
14
14
|
const supports_color_1 = require("supports-color");
|
|
15
15
|
const has_ansi_1 = __importDefault(require("has-ansi"));
|
|
16
|
-
const DEFAULT_CUCUMBER_PUBLISH_URL = 'https://
|
|
16
|
+
const DEFAULT_CUCUMBER_PUBLISH_URL = 'https://reports.cucumber.io/api/reports';
|
|
17
17
|
exports.publishPlugin = {
|
|
18
18
|
type: 'plugin',
|
|
19
|
-
coordinator: async ({ on, logger, options, environment }) => {
|
|
19
|
+
coordinator: async ({ on, emit, logger, options, environment }) => {
|
|
20
20
|
if (!options) {
|
|
21
21
|
return undefined;
|
|
22
22
|
}
|
|
23
23
|
const { url = DEFAULT_CUCUMBER_PUBLISH_URL, token } = options;
|
|
24
|
-
const headers = {
|
|
24
|
+
const headers = {
|
|
25
|
+
Accept: 'application/json',
|
|
26
|
+
};
|
|
25
27
|
if (token !== undefined) {
|
|
26
28
|
headers.Authorization = `Bearer ${token}`;
|
|
27
29
|
}
|
|
28
30
|
const touchResponse = await fetch(url, { headers });
|
|
29
|
-
|
|
31
|
+
if (touchResponse.status >= 500) {
|
|
32
|
+
return () => {
|
|
33
|
+
logger.error(`Failed to publish report to ${new URL(url).origin} with status ${touchResponse.status}`);
|
|
34
|
+
logger.debug(touchResponse);
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const touchResult = (await touchResponse.json());
|
|
30
38
|
if (!touchResponse.ok) {
|
|
31
39
|
return () => {
|
|
32
|
-
|
|
33
|
-
environment.stderr.write(sanitisePublishOutput(banner, environment.stderr) + '\n');
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
logger.error(`Failed to publish report to ${new URL(url).origin} with status ${touchResponse.status}`);
|
|
37
|
-
logger.debug(touchResponse);
|
|
38
|
-
}
|
|
40
|
+
environment.stderr.write(sanitisePublishOutput(touchResult.banner, environment.stderr) + '\n');
|
|
39
41
|
};
|
|
40
42
|
}
|
|
43
|
+
if (touchResult.url) {
|
|
44
|
+
emit('publish:url', touchResult.url);
|
|
45
|
+
}
|
|
41
46
|
const uploadUrl = touchResponse.headers.get('Location');
|
|
42
47
|
const tempDir = await (0, promises_2.mkdtemp)(node_path_1.default.join((0, node_os_1.tmpdir)(), `cucumber-js-publish-`));
|
|
43
48
|
const tempFilePath = node_path_1.default.join(tempDir, 'envelopes.jsonl.gz');
|
|
@@ -62,7 +67,8 @@ exports.publishPlugin = {
|
|
|
62
67
|
duplex: 'half',
|
|
63
68
|
});
|
|
64
69
|
if (uploadResponse.ok) {
|
|
65
|
-
environment.stderr.write(sanitisePublishOutput(banner, environment.stderr) +
|
|
70
|
+
environment.stderr.write(sanitisePublishOutput(touchResult.banner, environment.stderr) +
|
|
71
|
+
'\n');
|
|
66
72
|
}
|
|
67
73
|
else {
|
|
68
74
|
logger.error(`Failed to upload report to ${new URL(uploadUrl).origin} with status ${uploadResponse.status}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish_plugin.js","sourceRoot":"","sources":["../../src/publish/publish_plugin.ts"],"names":[],"mappings":";;;;;;AACA,mDAA+C;AAC/C,yCAAoD;AACpD,+CAAgD;AAChD,0DAA4B;AAC5B,qCAAgC;AAChC,qCAA6D;AAC7D,yCAAsC;AACtC,mDAA8C;AAC9C,wDAA8B;
|
|
1
|
+
{"version":3,"file":"publish_plugin.js","sourceRoot":"","sources":["../../src/publish/publish_plugin.ts"],"names":[],"mappings":";;;;;;AACA,mDAA+C;AAC/C,yCAAoD;AACpD,+CAAgD;AAChD,0DAA4B;AAC5B,qCAAgC;AAChC,qCAA6D;AAC7D,yCAAsC;AACtC,mDAA8C;AAC9C,wDAA8B;AAQ9B,MAAM,4BAA4B,GAAG,yCAAyC,CAAA;AAEjE,QAAA,aAAa,GAAmB;IAC3C,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE;QAChE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,MAAM,EAAE,GAAG,GAAG,4BAA4B,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;QAC7D,MAAM,OAAO,GAA8B;YACzC,MAAM,EAAE,kBAAkB;SAC3B,CAAA;QACD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,CAAC,aAAa,GAAG,UAAU,KAAK,EAAE,CAAA;QAC3C,CAAC;QACD,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;QAEnD,IAAI,aAAa,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YAChC,OAAO,GAAG,EAAE;gBACV,MAAM,CAAC,KAAK,CACV,+BAA+B,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,gBAChD,aAAa,CAAC,MAChB,EAAE,CACH,CAAA;gBACD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;YAC7B,CAAC,CAAA;QACH,CAAC;QAED,MAAM,WAAW,GAAG,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,CAAgB,CAAA;QAE/D,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;YACtB,OAAO,GAAG,EAAE;gBACV,WAAW,CAAC,MAAM,CAAC,KAAK,CACtB,qBAAqB,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CACrE,CAAA;YACH,CAAC,CAAA;QACH,CAAC;QAED,IAAI,WAAW,CAAC,GAAG,EAAE,CAAC;YACpB,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,GAAG,CAAC,CAAA;QACtC,CAAC;QAED,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QACvD,MAAM,OAAO,GAAG,MAAM,IAAA,kBAAO,EAAC,mBAAI,CAAC,IAAI,CAAC,IAAA,gBAAM,GAAE,EAAE,sBAAsB,CAAC,CAAC,CAAA;QAC1E,MAAM,YAAY,GAAG,mBAAI,CAAC,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAA;QAC7D,MAAM,WAAW,GAAG,IAAA,sBAAU,GAAE,CAAA;QAChC,MAAM,eAAe,GAAG,IAAA,mBAAQ,EAC9B,WAAW,EACX,IAAA,2BAAiB,EAAC,YAAY,CAAC,CAChC,CAAA;QACD,EAAE,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA;QAEzE,OAAO,GAAG,EAAE;YACV,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBACnC,WAAW,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;oBACzB,MAAM,eAAe,CAAA;oBACrB,MAAM,KAAK,GAAG,MAAM,IAAA,eAAI,EAAC,YAAY,CAAC,CAAA;oBACtC,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAA;oBAC3C,MAAM,CAAC,KAAK,CACV,8DAA8D,EAC9D,aAAa,CACd,CAAA;oBACD,MAAM,cAAc,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;wBAC5C,MAAM,EAAE,KAAK;wBACb,OAAO,EAAE;4BACP,cAAc,EAAE,mBAAmB;4BACnC,kBAAkB,EAAE,MAAM;4BAC1B,gBAAgB,EAAE,aAAa;yBAChC;wBACD,IAAI,EAAE,IAAA,0BAAgB,EAAC,YAAY,CAAC;wBACpC,MAAM,EAAE,MAAM;qBACf,CAAC,CAAA;oBACF,IAAI,cAAc,CAAC,EAAE,EAAE,CAAC;wBACtB,WAAW,CAAC,MAAM,CAAC,KAAK,CACtB,qBAAqB,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC;4BAC3D,IAAI,CACP,CAAA;oBACH,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,KAAK,CACV,8BACE,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,MACrB,gBAAgB,cAAc,CAAC,MAAM,EAAE,CACxC,CAAA;wBACD,MAAM,CAAC,KAAK,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC,CAAA;oBAC3C,CAAC;oBACD,OAAO,EAAE,CAAA;gBACX,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC,CAAA;IACH,CAAC;CACF,CAAA;AAED;;;;;GAKG;AACH,SAAS,qBAAqB,CAAC,GAAW,EAAE,MAAgB;IAC1D,IAAI,CAAC,IAAA,8BAAa,EAAC,MAAM,CAAC,IAAI,IAAA,kBAAO,EAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,OAAO,IAAA,oCAAwB,EAAC,GAAG,CAAC,CAAA;IACtC,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC","sourcesContent":["import { Writable } from 'node:stream'\nimport { pipeline } from 'node:stream/promises'\nimport { stripVTControlCharacters } from 'node:util'\nimport { mkdtemp, stat } from 'node:fs/promises'\nimport path from 'node:path'\nimport { tmpdir } from 'node:os'\nimport { createReadStream, createWriteStream } from 'node:fs'\nimport { createGzip } from 'node:zlib'\nimport { supportsColor } from 'supports-color'\nimport hasAnsi from 'has-ansi'\nimport { InternalPlugin } from '../plugin'\n\ntype TouchResult = {\n banner: string\n url?: string\n}\n\nconst DEFAULT_CUCUMBER_PUBLISH_URL = 'https://reports.cucumber.io/api/reports'\n\nexport const publishPlugin: InternalPlugin = {\n type: 'plugin',\n coordinator: async ({ on, emit, logger, options, environment }) => {\n if (!options) {\n return undefined\n }\n const { url = DEFAULT_CUCUMBER_PUBLISH_URL, token } = options\n const headers: { [key: string]: string } = {\n Accept: 'application/json',\n }\n if (token !== undefined) {\n headers.Authorization = `Bearer ${token}`\n }\n const touchResponse = await fetch(url, { headers })\n\n if (touchResponse.status >= 500) {\n return () => {\n logger.error(\n `Failed to publish report to ${new URL(url).origin} with status ${\n touchResponse.status\n }`\n )\n logger.debug(touchResponse)\n }\n }\n\n const touchResult = (await touchResponse.json()) as TouchResult\n\n if (!touchResponse.ok) {\n return () => {\n environment.stderr.write(\n sanitisePublishOutput(touchResult.banner, environment.stderr) + '\\n'\n )\n }\n }\n\n if (touchResult.url) {\n emit('publish:url', touchResult.url)\n }\n\n const uploadUrl = touchResponse.headers.get('Location')\n const tempDir = await mkdtemp(path.join(tmpdir(), `cucumber-js-publish-`))\n const tempFilePath = path.join(tempDir, 'envelopes.jsonl.gz')\n const writeStream = createGzip()\n const finishedWriting = pipeline(\n writeStream,\n createWriteStream(tempFilePath)\n )\n on('message', (value) => writeStream.write(JSON.stringify(value) + '\\n'))\n\n return () => {\n return new Promise<void>((resolve) => {\n writeStream.end(async () => {\n await finishedWriting\n const stats = await stat(tempFilePath)\n const contentLength = stats.size.toString()\n logger.debug(\n 'Uploading envelopes to Cucumber Reports with content length:',\n contentLength\n )\n const uploadResponse = await fetch(uploadUrl, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/jsonl',\n 'Content-Encoding': 'gzip',\n 'Content-Length': contentLength,\n },\n body: createReadStream(tempFilePath),\n duplex: 'half',\n })\n if (uploadResponse.ok) {\n environment.stderr.write(\n sanitisePublishOutput(touchResult.banner, environment.stderr) +\n '\\n'\n )\n } else {\n logger.error(\n `Failed to upload report to ${\n new URL(uploadUrl).origin\n } with status ${uploadResponse.status}`\n )\n logger.debug(await uploadResponse.text())\n }\n resolve()\n })\n })\n }\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: Writable) {\n if (!supportsColor(stderr) && hasAnsi(raw)) {\n return stripVTControlCharacters(raw)\n }\n return raw\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const shardingPlugin:
|
|
1
|
+
import { InternalPlugin } from '../plugin';
|
|
2
|
+
export declare const shardingPlugin: InternalPlugin;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharding_plugin.js","sourceRoot":"","sources":["../../src/sharding/sharding_plugin.ts"],"names":[],"mappings":";;;AAEa,QAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"sharding_plugin.js","sourceRoot":"","sources":["../../src/sharding/sharding_plugin.ts"],"names":[],"mappings":";;;AAEa,QAAA,cAAc,GAAmB;IAC5C,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE;QAC5C,SAAS,CAAC,gBAAgB,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;YAC/C,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACnB,OAAO,UAAU,CAAA;YACnB,CAAC;YAED,MAAM,CAAC,aAAa,EAAE,aAAa,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC/D,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,GAAG,CAAC,CAAA;YAClD,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,CAAA;YAE9C,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,KAAK,UAAU,CAAC,CAAA;QACnE,CAAC,CAAC,CAAA;IACJ,CAAC;CACF,CAAA","sourcesContent":["import { InternalPlugin } from '../plugin'\n\nexport const shardingPlugin: InternalPlugin = {\n type: 'plugin',\n coordinator: async ({ transform, options }) => {\n transform('pickles:filter', async (allPickles) => {\n if (!options.shard) {\n return allPickles\n }\n\n const [shardIndexStr, shardTotalStr] = options.shard.split('/')\n const shardIndex = parseInt(shardIndexStr, 10) - 1\n const shardTotal = parseInt(shardTotalStr, 10)\n\n return allPickles.filter((_, i) => i % shardTotal === shardIndex)\n })\n },\n}\n"]}
|
package/lib/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "12.
|
|
1
|
+
export declare const version = "12.9.0";
|
package/lib/version.js
CHANGED
package/lib/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;;AAAA,2BAA2B;AACd,QAAA,OAAO,GAAG,QAAQ,CAAA","sourcesContent":["// Generated by genversion.\nexport const version = '12.
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;;AAAA,2BAA2B;AACd,QAAA,OAAO,GAAG,QAAQ,CAAA","sourcesContent":["// Generated by genversion.\nexport const version = '12.9.0'\n"]}
|
package/package.json
CHANGED