@lynxwall/cucumber-tsflow 7.2.0 → 7.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +59 -35
  2. package/lib/api/load-configuration.js +60 -16
  3. package/lib/api/load-configuration.js.map +1 -1
  4. package/lib/bindings/binding-context.d.ts +40 -4
  5. package/lib/bindings/binding-context.js +50 -6
  6. package/lib/bindings/binding-context.js.map +1 -1
  7. package/lib/bindings/binding-decorator.js +32 -9
  8. package/lib/bindings/binding-decorator.js.map +1 -1
  9. package/lib/bindings/binding-registry.js +10 -0
  10. package/lib/bindings/binding-registry.js.map +1 -1
  11. package/lib/bindings/hook-decorators.js +4 -3
  12. package/lib/bindings/hook-decorators.js.map +1 -1
  13. package/lib/bindings/step-decorators.js +12 -9
  14. package/lib/bindings/step-decorators.js.map +1 -1
  15. package/lib/cli/argv-parser.js +1 -2
  16. package/lib/cli/argv-parser.js.map +1 -1
  17. package/lib/runtime/parallel/worker.js +1 -1
  18. package/lib/runtime/parallel/worker.js.map +1 -1
  19. package/lib/runtime/test-case-runner.d.ts +2 -1
  20. package/lib/runtime/test-case-runner.js +8 -5
  21. package/lib/runtime/test-case-runner.js.map +1 -1
  22. package/lib/transpilers/esbuild-transpiler.d.ts +1 -1
  23. package/lib/transpilers/esbuild-transpiler.js.map +1 -1
  24. package/lib/transpilers/esbuild.js.map +1 -1
  25. package/lib/transpilers/esm/esbuild-transpiler-cjs.js +2174 -0
  26. package/lib/transpilers/esm/esbuild-transpiler.mjs +19 -0
  27. package/lib/transpilers/esm/esbuild.mjs +141 -0
  28. package/lib/transpilers/esm/esmbuild-transpiler.d.ts +4 -0
  29. package/lib/transpilers/esm/esmbuild-transpiler.js +19 -0
  30. package/lib/transpilers/esm/esmbuild-transpiler.js.map +1 -0
  31. package/lib/transpilers/esm/esmbuild.d.ts +12 -0
  32. package/lib/transpilers/esm/esmbuild.js +72 -0
  33. package/lib/transpilers/esm/esmbuild.js.map +1 -0
  34. package/lib/transpilers/esm/esmnode.d.ts +1 -0
  35. package/lib/transpilers/esm/esmnode.js +8 -0
  36. package/lib/transpilers/esm/esmnode.js.map +1 -0
  37. package/lib/transpilers/esm/esmvue.d.ts +1 -0
  38. package/lib/transpilers/esm/esmvue.js +29 -0
  39. package/lib/transpilers/esm/esmvue.js.map +1 -0
  40. package/lib/transpilers/esm/esnode-loader.mjs +9 -0
  41. package/lib/transpilers/esm/esvue-loader.mjs +9 -0
  42. package/lib/transpilers/esm/loader-utils.mjs +356 -0
  43. package/lib/transpilers/esm/tsnode-esm.d.ts +1 -0
  44. package/lib/transpilers/esm/tsnode-esm.js +25 -0
  45. package/lib/transpilers/esm/tsnode-esm.js.map +1 -0
  46. package/lib/transpilers/esm/tsnode-exp-esm.d.ts +1 -0
  47. package/lib/transpilers/esm/tsnode-exp-esm.js +19 -0
  48. package/lib/transpilers/esm/tsnode-exp-esm.js.map +1 -0
  49. package/lib/transpilers/esm/tsnode-loader.mjs +107 -0
  50. package/lib/transpilers/esm/tsnode-service.mjs +40 -0
  51. package/lib/transpilers/esm/tsvue-esm.d.ts +1 -0
  52. package/lib/transpilers/esm/tsvue-esm.js +40 -0
  53. package/lib/transpilers/esm/tsvue-esm.js.map +1 -0
  54. package/lib/transpilers/esm/tsvue-exp-esm.d.ts +1 -0
  55. package/lib/transpilers/esm/tsvue-exp-esm.js +40 -0
  56. package/lib/transpilers/esm/tsvue-exp-esm.js.map +1 -0
  57. package/lib/transpilers/esm/vue-jsdom-setup.mjs +19 -0
  58. package/lib/transpilers/esm/vue-loader.mjs +113 -0
  59. package/lib/transpilers/esm/vue-sfc-compiler.mjs +216 -0
  60. package/lib/transpilers/esnode.js +1 -1
  61. package/lib/transpilers/esnode.js.map +1 -1
  62. package/lib/transpilers/esvue.js +1 -1
  63. package/lib/transpilers/esvue.js.map +1 -1
  64. package/lib/transpilers/tsnode-exp.js +1 -1
  65. package/lib/transpilers/tsnode-exp.js.map +1 -1
  66. package/lib/transpilers/tsnode.js +1 -1
  67. package/lib/transpilers/tsnode.js.map +1 -1
  68. package/lib/transpilers/tsvue-exp.js +1 -1
  69. package/lib/transpilers/tsvue-exp.js.map +1 -1
  70. package/lib/transpilers/tsvue.js +2 -2
  71. package/lib/transpilers/tsvue.js.map +1 -1
  72. package/lib/transpilers/vue-sfc/index.js.map +1 -1
  73. package/lib/tsconfig.node.tsbuildinfo +1 -1
  74. package/lib/version.d.ts +1 -1
  75. package/lib/version.js +1 -1
  76. package/lib/version.js.map +1 -1
  77. package/package.json +27 -17
@@ -0,0 +1,356 @@
1
+ import { compileVueSFC } from './vue-sfc-compiler.mjs';
2
+ import { fileURLToPath, pathToFileURL } from 'url';
3
+ import { existsSync } from 'fs';
4
+ import path from 'path';
5
+ import { createMatchPath, loadConfig } from 'tsconfig-paths';
6
+ import { createEsmHooks } from './tsnode-service.mjs';
7
+
8
+ // Shared asset extensions
9
+ export const ASSET_EXTENSIONS = [
10
+ '.jpg',
11
+ '.jpeg',
12
+ '.png',
13
+ '.gif',
14
+ '.svg',
15
+ '.webp',
16
+ '.ico',
17
+ '.woff',
18
+ '.woff2',
19
+ '.ttf',
20
+ '.eot'
21
+ ];
22
+ export const CODE_EXTENSIONS = ['.vue', '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'];
23
+
24
+ // TSConfig paths initialization
25
+ let matchPath;
26
+ export function initializeTsconfigPaths() {
27
+ if (matchPath) return matchPath;
28
+
29
+ try {
30
+ const configLoaderResult = loadConfig(process.cwd());
31
+ if (configLoaderResult.resultType === 'success') {
32
+ matchPath = createMatchPath(
33
+ configLoaderResult.absoluteBaseUrl,
34
+ configLoaderResult.paths,
35
+ configLoaderResult.mainFields,
36
+ configLoaderResult.addMatchAll
37
+ );
38
+ } else {
39
+ console.warn('>>> loader: no tsconfig paths found');
40
+ }
41
+ } catch (error) {
42
+ console.error('>>> loader: failed to load tsconfig paths:', error);
43
+ }
44
+
45
+ return matchPath;
46
+ }
47
+
48
+ // Extension resolution helper
49
+ export async function resolveWithExtensions(specifier, parentURL, extensions = CODE_EXTENSIONS) {
50
+ let resolvedPath;
51
+
52
+ if (specifier.startsWith('file://')) {
53
+ // Handle file:// URLs
54
+ resolvedPath = fileURLToPath(specifier);
55
+ } else {
56
+ // Handle relative paths
57
+ const parentPath = fileURLToPath(parentURL);
58
+ const parentDir = path.dirname(parentPath);
59
+ resolvedPath = path.resolve(parentDir, specifier);
60
+ }
61
+ // Try various extensions
62
+ for (const ext of extensions) {
63
+ const fullPath = resolvedPath + ext;
64
+
65
+ if (existsSync(fullPath)) {
66
+ const result = pathToFileURL(fullPath).href;
67
+ return result;
68
+ }
69
+ }
70
+
71
+ // Try index files
72
+ for (const ext of extensions) {
73
+ const indexPath = path.join(resolvedPath, 'index' + ext);
74
+ if (existsSync(indexPath)) {
75
+ return pathToFileURL(indexPath).href;
76
+ }
77
+ }
78
+
79
+ return null;
80
+ }
81
+
82
+ const pathResolutionCache = new Map();
83
+
84
+ export function resolveTsconfigPaths(specifier) {
85
+ // Fast path: skip what we know won't match
86
+ if (
87
+ specifier.startsWith('.') ||
88
+ specifier.startsWith('/') ||
89
+ specifier.startsWith('file:') ||
90
+ specifier.startsWith('node:')
91
+ ) {
92
+ return null;
93
+ }
94
+
95
+ // Check cache
96
+ if (pathResolutionCache.has(specifier)) {
97
+ return pathResolutionCache.get(specifier);
98
+ }
99
+
100
+ const matchPath = initializeTsconfigPaths();
101
+ if (!matchPath) {
102
+ pathResolutionCache.set(specifier, null);
103
+ return null;
104
+ }
105
+
106
+ // Try direct match first
107
+ const mapped = matchPath(specifier);
108
+ if (mapped) {
109
+ const result = {
110
+ url: pathToFileURL(mapped).href,
111
+ shortCircuit: true
112
+ };
113
+ pathResolutionCache.set(specifier, result);
114
+ return result;
115
+ }
116
+
117
+ // Try with extensions if no extension present
118
+ if (!path.extname(specifier)) {
119
+ for (const ext of ['.ts', '.js', '.mjs', '.vue']) {
120
+ const mappedWithExt = matchPath(specifier + ext);
121
+ if (mappedWithExt) {
122
+ const result = {
123
+ url: pathToFileURL(mappedWithExt).href,
124
+ shortCircuit: true
125
+ };
126
+ pathResolutionCache.set(specifier, result);
127
+ return result;
128
+ }
129
+ }
130
+ }
131
+
132
+ pathResolutionCache.set(specifier, null);
133
+ return null;
134
+ }
135
+
136
+ // Asset loader helper
137
+ export function loadAsset(url) {
138
+ const filePath = fileURLToPath(url);
139
+ return {
140
+ format: 'module',
141
+ source: `export default ${JSON.stringify(filePath)};`,
142
+ shortCircuit: true
143
+ };
144
+ }
145
+
146
+ // Vue style configuration helper
147
+ export function shouldEnableVueStyle() {
148
+ // Check if styles should be enabled (from environment or config)
149
+ // Vue styles are disabled by default. However, user could enable them when importing from compiled libraries
150
+ return (
151
+ global.enableVueStyle === true ||
152
+ process.env.CUCUMBER_ENABLE_VUE_STYLE === 'true' ||
153
+ process.env.enableVueStyle === 'true'
154
+ );
155
+ }
156
+
157
+ async function transformImports(code, parentURL) {
158
+ // Match various import patterns
159
+ const importRegex =
160
+ /(?:import|export)\s+(?:(?:\{[^}]*\}|\*\s+as\s+\w+|\w+|type\s+\{[^}]*\}|type\s+\w+)\s+from\s+)?['"]([^'"]+)['"]/g;
161
+
162
+ const matches = [...code.matchAll(importRegex)];
163
+ let transformed = code;
164
+
165
+ for (const match of matches) {
166
+ const specifier = match[1];
167
+
168
+ // Skip if it's already a relative path or absolute URL
169
+ if (specifier.startsWith('.') || specifier.startsWith('/') || specifier.startsWith('file:')) {
170
+ continue;
171
+ }
172
+
173
+ // Try to resolve with tsconfig paths
174
+ const resolved = resolveTsconfigPaths(specifier);
175
+ if (resolved) {
176
+ // Convert the resolved path to a relative import from the parent file
177
+ const parentDir = path.dirname(fileURLToPath(parentURL));
178
+ const resolvedPath = fileURLToPath(resolved.url);
179
+ let relativePath = path.relative(parentDir, resolvedPath).replace(/\\/g, '/');
180
+
181
+ // Ensure it starts with ./ or ../
182
+ if (!relativePath.startsWith('.')) {
183
+ relativePath = './' + relativePath;
184
+ }
185
+
186
+ // Replace the specifier in the import statement
187
+ const originalImport = match[0];
188
+ const newImport = originalImport.replace(specifier, relativePath);
189
+ transformed = transformed.replace(originalImport, newImport);
190
+ }
191
+ }
192
+
193
+ return transformed;
194
+ }
195
+
196
+ export async function loadVue(url, context, nextLoad) {
197
+ const { source } = await nextLoad(url, { ...context, format: 'module' });
198
+ const code = source.toString();
199
+ const filename = fileURLToPath(url);
200
+
201
+ const compiled = compileVueSFC(code, filename, {
202
+ enableStyle: shouldEnableVueStyle()
203
+ });
204
+
205
+ // Transform imports to resolve path aliases
206
+ const transformed = await transformImports(compiled.code, url);
207
+
208
+ return {
209
+ format: 'module',
210
+ source: transformed,
211
+ shortCircuit: true
212
+ };
213
+ }
214
+
215
+ /**
216
+ * Resolves module specifiers with support for TypeScript paths, extensions, and more
217
+ * @param {string} specifier - The module specifier to resolve
218
+ * @param {object} context - The loader context
219
+ * @param {object} options - Resolution options
220
+ * @param {string} options.logPrefix - Prefix for log messages
221
+ * @param {boolean} options.checkExtensions - Whether to try adding extensions
222
+ * @param {boolean} options.handleTsFiles - Whether to delegate .ts files to ts-node
223
+ * @param {object} options.tsNodeHooks - The ts-node hooks (if handleTsFiles is true)
224
+ * @param {function} options.nextResolve - The next resolver in the chain
225
+ * @returns {Promise<object|null>} The resolution result or null
226
+ */
227
+ export async function resolveSpecifier(specifier, context, options = {}) {
228
+ const { checkExtensions = true, handleTsFiles = false, tsNodeHooks = null, nextResolve } = options;
229
+
230
+ // 1. Handle TypeScript path mappings first
231
+ const mappedResult = resolveTsconfigPaths(specifier);
232
+ if (mappedResult) {
233
+ // Check if the mapped result needs extension resolution
234
+ const mappedUrl = mappedResult.url;
235
+ if (checkExtensions && !path.extname(mappedUrl)) {
236
+ // Try to resolve with extensions
237
+ const resolved = await resolveWithExtensions(mappedUrl, context.parentURL);
238
+ if (resolved) {
239
+ return { url: resolved, shortCircuit: true };
240
+ }
241
+ }
242
+
243
+ return mappedResult;
244
+ }
245
+
246
+ // 2. Handle TypeScript files if requested
247
+ if (handleTsFiles && tsNodeHooks && (specifier.endsWith('.ts') || specifier.endsWith('.tsx'))) {
248
+ try {
249
+ return await tsNodeHooks.resolve(specifier, context, nextResolve);
250
+ } catch (error) {
251
+ // Fall through to extension resolution
252
+ }
253
+ }
254
+
255
+ // 3. Extension resolution for relative imports and file:// URLs
256
+ if (checkExtensions && (specifier.startsWith('.') || specifier.startsWith('/') || specifier.startsWith('file://'))) {
257
+ const hasExtension = path.extname(specifier) !== '';
258
+
259
+ if (!hasExtension && context.parentURL) {
260
+ const resolved = await resolveWithExtensions(specifier, context.parentURL);
261
+ if (resolved) {
262
+ return { url: resolved, shortCircuit: true };
263
+ }
264
+ }
265
+ }
266
+
267
+ // 4. No resolution found
268
+ return null;
269
+ }
270
+
271
+ // Cache for different ESM hooks by transpiler path
272
+ const esmHooksCache = new Map();
273
+
274
+ export async function getEsmHooks(transpilerPath, loaderName = 'loader') {
275
+ if (esmHooksCache.has(transpilerPath)) {
276
+ return esmHooksCache.get(transpilerPath);
277
+ }
278
+
279
+ try {
280
+ const hooks = await createEsmHooks(transpilerPath);
281
+ esmHooksCache.set(transpilerPath, hooks);
282
+ return hooks;
283
+ } catch (error) {
284
+ console.error(`>>> ${loaderName}: Failed to load ESM hooks with transpiler ${transpilerPath}:`, error);
285
+ throw error;
286
+ }
287
+ }
288
+
289
+ // Helper to create hook exports
290
+ export function createHookExports(getHooksFn) {
291
+ return {
292
+ getFormat: async (...args) => (await getHooksFn()).getFormat(...args),
293
+ transformSource: async (...args) => (await getHooksFn()).transformSource(...args)
294
+ };
295
+ }
296
+
297
+ // Common loader factory for esbuild-based loaders
298
+ export function createEsbuildLoader(options = {}) {
299
+ const {
300
+ loaderName = 'loader',
301
+ handleVue = false,
302
+ transpilerPath = '@lynxwall/cucumber-tsflow/lib/transpilers/esm/esbuild-transpiler-cjs'
303
+ } = options;
304
+
305
+ const getLocalEsmHooks = () => getEsmHooks(transpilerPath, loaderName);
306
+
307
+ return {
308
+ resolve: async (specifier, context, nextResolve) => {
309
+ const resolved = await resolveSpecifier(specifier, context, {
310
+ checkExtensions: true,
311
+ handleTsFiles: true,
312
+ tsNodeHooks: await getLocalEsmHooks(),
313
+ nextResolve
314
+ });
315
+
316
+ if (resolved) {
317
+ return resolved;
318
+ }
319
+
320
+ return nextResolve(specifier, context);
321
+ },
322
+
323
+ load: async (url, context, nextLoad) => {
324
+ // Handle asset files
325
+ const ext = path.extname(url).toLowerCase();
326
+ if (ASSET_EXTENSIONS.includes(ext)) {
327
+ return loadAsset(url);
328
+ }
329
+
330
+ // Handle Vue files if enabled
331
+ if (handleVue && url.endsWith('.vue')) {
332
+ try {
333
+ return loadVue(url, context, nextLoad);
334
+ } catch (error) {
335
+ console.error(`>>> ${loaderName}: Failed to compile Vue SFC ${url}:`, error);
336
+ throw new Error(`Failed to compile Vue SFC ${url}: ${error.message}`);
337
+ }
338
+ }
339
+
340
+ // Handle TypeScript files
341
+ if (url.endsWith('.ts') || url.endsWith('.tsx')) {
342
+ try {
343
+ const tsNodeHooks = await getLocalEsmHooks();
344
+ return tsNodeHooks.load(url, context, nextLoad);
345
+ } catch (error) {
346
+ console.error(`>>> ${loaderName}: ts-node failed for ${url}:`, error);
347
+ throw error;
348
+ }
349
+ }
350
+
351
+ return nextLoad(url, context);
352
+ },
353
+
354
+ ...createHookExports(getLocalEsmHooks)
355
+ };
356
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require('ts-node').register({
4
+ compilerOptions: {
5
+ module: 'es2022',
6
+ target: 'ESNext',
7
+ moduleResolution: 'node',
8
+ esModuleInterop: true,
9
+ strict: true,
10
+ allowJs: true,
11
+ allowSyntheticDefaultImports: true,
12
+ experimentalDecorators: false,
13
+ resolveJsonModule: true,
14
+ skipLibCheck: true,
15
+ forceConsistentCasingInFileNames: true,
16
+ lib: ['es2022', 'esnext.decorators']
17
+ },
18
+ 'ts-node': {
19
+ esm: true,
20
+ experimentalSpecifierResolution: 'node'
21
+ },
22
+ transpileOnly: true
23
+ });
24
+ require('tsconfig-paths').register();
25
+ //# sourceMappingURL=tsnode-esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsnode-esm.js","sourceRoot":"","sources":["../../../src/transpilers/esm/tsnode-esm.ts"],"names":[],"mappings":";;AAAA,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC;IAC3B,eAAe,EAAE;QAChB,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,QAAQ;QAChB,gBAAgB,EAAE,MAAM;QACxB,eAAe,EAAE,IAAI;QACrB,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,IAAI;QACb,4BAA4B,EAAE,IAAI;QAClC,sBAAsB,EAAE,KAAK;QAC7B,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,IAAI;QAClB,gCAAgC,EAAE,IAAI;QACtC,GAAG,EAAE,CAAC,QAAQ,EAAE,mBAAmB,CAAC;KACpC;IACD,SAAS,EAAE;QACV,GAAG,EAAE,IAAI;QACT,+BAA+B,EAAE,MAAM;KACvC;IACD,aAAa,EAAE,IAAI;CACnB,CAAC,CAAC;AAEH,OAAO,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,CAAC","sourcesContent":["require('ts-node').register({\r\n\tcompilerOptions: {\r\n\t\tmodule: 'es2022',\r\n\t\ttarget: 'ESNext',\r\n\t\tmoduleResolution: 'node',\r\n\t\tesModuleInterop: true,\r\n\t\tstrict: true,\r\n\t\tallowJs: true,\r\n\t\tallowSyntheticDefaultImports: true,\r\n\t\texperimentalDecorators: false,\r\n\t\tresolveJsonModule: true,\r\n\t\tskipLibCheck: true,\r\n\t\tforceConsistentCasingInFileNames: true,\r\n\t\tlib: ['es2022', 'esnext.decorators']\r\n\t},\r\n\t'ts-node': {\r\n\t\tesm: true,\r\n\t\texperimentalSpecifierResolution: 'node'\r\n\t},\r\n\ttranspileOnly: true\r\n});\r\n\r\nrequire('tsconfig-paths').register();\r\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require('ts-node/esm').register({
4
+ compilerOptions: {
5
+ module: 'nodeNext',
6
+ target: 'es2022',
7
+ strict: true,
8
+ allowJs: true,
9
+ allowSyntheticDefaultImports: true,
10
+ esModuleInterop: true,
11
+ experimentalDecorators: true,
12
+ resolveJsonModule: true,
13
+ skipLibCheck: true,
14
+ lib: ['es2022']
15
+ },
16
+ transpileOnly: true
17
+ });
18
+ require('tsconfig-paths').register();
19
+ //# sourceMappingURL=tsnode-exp-esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsnode-exp-esm.js","sourceRoot":"","sources":["../../../src/transpilers/esm/tsnode-exp-esm.ts"],"names":[],"mappings":";;AAEA,OAAO,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC;IAC/B,eAAe,EAAE;QAChB,MAAM,EAAE,UAAU;QAClB,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,IAAI;QACb,4BAA4B,EAAE,IAAI;QAClC,eAAe,EAAE,IAAI;QACrB,sBAAsB,EAAE,IAAI;QAC5B,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,IAAI;QAClB,GAAG,EAAE,CAAC,QAAQ,CAAC;KACf;IACD,aAAa,EAAE,IAAI;CACnB,CAAC,CAAC;AAEH,OAAO,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,CAAC","sourcesContent":["import { SourceMap } from 'node:module';\r\n\r\nrequire('ts-node/esm').register({\r\n\tcompilerOptions: {\r\n\t\tmodule: 'nodeNext',\r\n\t\ttarget: 'es2022',\r\n\t\tstrict: true,\r\n\t\tallowJs: true,\r\n\t\tallowSyntheticDefaultImports: true,\r\n\t\tesModuleInterop: true,\r\n\t\texperimentalDecorators: true,\r\n\t\tresolveJsonModule: true,\r\n\t\tskipLibCheck: true,\r\n\t\tlib: ['es2022']\r\n\t},\r\n\ttranspileOnly: true\r\n});\r\n\r\nrequire('tsconfig-paths').register();\r\n"]}
@@ -0,0 +1,107 @@
1
+ import { pathToFileURL } from 'url';
2
+ import { createRequire } from 'node:module';
3
+ import { resolveSpecifier } from './loader-utils.mjs';
4
+ import { loadConfig } from 'tsconfig-paths';
5
+ import path from 'path';
6
+
7
+ const require = createRequire(import.meta.url);
8
+
9
+ // Load tsconfig to get paths
10
+ const configLoaderResult = loadConfig(process.cwd());
11
+ let paths = {};
12
+ let baseUrl = './';
13
+
14
+ if (configLoaderResult.resultType === 'success') {
15
+ paths = configLoaderResult.paths || {};
16
+ baseUrl = configLoaderResult.baseUrl || './';
17
+ }
18
+
19
+ // Create ts-node service with our configuration
20
+ const tsNode = require('ts-node-maintained');
21
+
22
+ const service = tsNode.create({
23
+ esm: true,
24
+ experimentalSpecifierResolution: 'node',
25
+ files: true,
26
+ transpileOnly: true,
27
+ compilerOptions: {
28
+ experimentalDecorators: process.env.CUCUMBER_EXPERIMENTAL_DECORATORS === 'true',
29
+ module: 'ESNext',
30
+ target: 'ES2022',
31
+ // Add path mapping to ts-node's compiler options
32
+ baseUrl: baseUrl,
33
+ paths: paths
34
+ }
35
+ });
36
+
37
+ // Create ESM hooks from the service
38
+ const esmHooks = tsNode.createEsmHooks(service);
39
+
40
+ export async function resolve(specifier, context, nextResolve) {
41
+ // Try common resolution logic (includes path mapping + extension resolution)
42
+ const resolved = await resolveSpecifier(specifier, context, {
43
+ checkExtensions: true,
44
+ handleTsFiles: true,
45
+ tsNodeHooks: esmHooks,
46
+ nextResolve
47
+ });
48
+
49
+ if (resolved) {
50
+ return resolved;
51
+ }
52
+
53
+ // Fall back to ts-node's resolver
54
+ return esmHooks.resolve(specifier, context, nextResolve);
55
+ }
56
+
57
+ export const load = async (url, context, nextLoad) => {
58
+ // Only intercept TypeScript files for path rewriting
59
+ if (url.endsWith('.ts') || url.endsWith('.tsx')) {
60
+ // First, let ts-node load the file
61
+ const result = await esmHooks.load(url, context, nextLoad);
62
+
63
+ // If we have path mappings, check if we need to rewrite the source
64
+ if (configLoaderResult.resultType === 'success' && configLoaderResult.paths) {
65
+ let code = result.source.toString();
66
+ let modified = false;
67
+
68
+ for (const [pattern, replacements] of Object.entries(configLoaderResult.paths)) {
69
+ // Convert TS path pattern to regex: @fixtures/* -> @fixtures/
70
+ const searchPattern = pattern.replace('/*', '/');
71
+ const searchRegex = new RegExp(`(from\\s+['"])${searchPattern}([^'"]+)(['"])`, 'g');
72
+
73
+ if (searchRegex.test(code)) {
74
+ // Get the replacement path (use first one if multiple)
75
+ const replacementPath = replacements[0].replace('/*', '');
76
+
77
+ code = code.replace(searchRegex, (match, prefix, importPath, suffix) => {
78
+ // Create the full path
79
+ const fullPath = path.join(configLoaderResult.absoluteBaseUrl, replacementPath, importPath);
80
+ // Convert to file:// URL for ESM
81
+ const fileUrl = pathToFileURL(fullPath).href;
82
+ return `${prefix}${fileUrl}${suffix}`;
83
+ });
84
+
85
+ modified = true;
86
+ }
87
+ }
88
+
89
+ if (modified) {
90
+ // Return the modified result
91
+ return {
92
+ ...result,
93
+ source: code
94
+ };
95
+ }
96
+ }
97
+
98
+ // Return the unmodified result from ts-node
99
+ return result;
100
+ }
101
+
102
+ // For non-TypeScript files, let ts-node handle it
103
+ return esmHooks.load(url, context, nextLoad);
104
+ };
105
+
106
+ export const getFormat = esmHooks.getFormat;
107
+ export const transformSource = esmHooks.transformSource;
@@ -0,0 +1,40 @@
1
+ import { createRequire } from 'module';
2
+
3
+ const require = createRequire(import.meta.url);
4
+ const tsNode = require('ts-node-maintained');
5
+
6
+ // Cache for different ts-node configurations
7
+ const serviceCache = new Map();
8
+
9
+ export function createTsNodeService(options = {}) {
10
+ const cacheKey = JSON.stringify(options);
11
+
12
+ if (serviceCache.has(cacheKey)) {
13
+ return serviceCache.get(cacheKey);
14
+ }
15
+
16
+ // Ensure ts-node respects tsconfig.json files
17
+ process.env.TS_NODE_FILES = process.env.TS_NODE_FILES || 'true';
18
+
19
+ const defaultOptions = {
20
+ esm: true,
21
+ experimentalSpecifierResolution: 'node',
22
+ files: true,
23
+ transpileOnly: true,
24
+ compilerOptions: {
25
+ experimentalDecorators: process.env.CUCUMBER_EXPERIMENTAL_DECORATORS === 'true',
26
+ module: 'ESNext',
27
+ target: 'ES2022'
28
+ }
29
+ };
30
+
31
+ const service = tsNode.create({ ...defaultOptions, ...options });
32
+ serviceCache.set(cacheKey, service);
33
+
34
+ return service;
35
+ }
36
+
37
+ export function createEsmHooks(transpiler) {
38
+ const service = createTsNodeService({ transpiler });
39
+ return tsNode.createEsmHooks(service);
40
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,40 @@
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
+ const hooks = require('require-extension-hooks');
7
+ const vue_sfc_1 = __importDefault(require("../vue-sfc"));
8
+ require('ts-node/esm').register({
9
+ compilerOptions: {
10
+ module: 'esnext',
11
+ target: 'es2022',
12
+ strict: true,
13
+ allowJs: true,
14
+ allowSyntheticDefaultImports: true,
15
+ esModuleInterop: true,
16
+ experimentalDecorators: false,
17
+ resolveJsonModule: true,
18
+ skipLibCheck: true,
19
+ lib: ['es2022', 'esnext.decorators']
20
+ },
21
+ transpileOnly: true
22
+ });
23
+ require('tsconfig-paths').register();
24
+ // Register jsdom globally and set SVGElement on global
25
+ require('jsdom-global')();
26
+ global.SVGElement = global.window.SVGElement;
27
+ hooks('vue').push(function (params) {
28
+ try {
29
+ const transformer = new vue_sfc_1.default({
30
+ exclude: ['(?:^|/)node_modules/', '(?:^|/)cucumber-tsflow/lib/']
31
+ });
32
+ const transformResult = transformer.transformCode(params.content, params.filename);
33
+ return transformResult.code;
34
+ }
35
+ catch (err) {
36
+ console.log(err);
37
+ }
38
+ return params.content;
39
+ });
40
+ //# sourceMappingURL=tsvue-esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsvue-esm.js","sourceRoot":"","sources":["../../../src/transpilers/esm/tsvue-esm.ts"],"names":[],"mappings":";;;;;AAAA,MAAM,KAAK,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;AACjD,yDAAwC;AAExC,OAAO,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC;IAC/B,eAAe,EAAE;QAChB,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,IAAI;QACb,4BAA4B,EAAE,IAAI;QAClC,eAAe,EAAE,IAAI;QACrB,sBAAsB,EAAE,KAAK;QAC7B,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,IAAI;QAClB,GAAG,EAAE,CAAC,QAAQ,EAAE,mBAAmB,CAAC;KACpC;IACD,aAAa,EAAE,IAAI;CACnB,CAAC,CAAC;AAEH,OAAO,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,CAAC;AAErC,uDAAuD;AACvD,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;AACzB,MAAc,CAAC,UAAU,GAAI,MAAc,CAAC,MAAM,CAAC,UAAU,CAAC;AAE/D,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,MAAW;IACtC,IAAI,CAAC;QACJ,MAAM,WAAW,GAAG,IAAI,iBAAc,CAAC;YACtC,OAAO,EAAE,CAAC,sBAAsB,EAAE,6BAA6B,CAAC;SAChE,CAAC,CAAC;QACH,MAAM,eAAe,GAAG,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAEnF,OAAO,eAAe,CAAC,IAAI,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC;AACvB,CAAC,CAAC,CAAC","sourcesContent":["const hooks = require('require-extension-hooks');\r\nimport VueTransformer from '../vue-sfc';\r\n\r\nrequire('ts-node/esm').register({\r\n\tcompilerOptions: {\r\n\t\tmodule: 'esnext',\r\n\t\ttarget: 'es2022',\r\n\t\tstrict: true,\r\n\t\tallowJs: true,\r\n\t\tallowSyntheticDefaultImports: true,\r\n\t\tesModuleInterop: true,\r\n\t\texperimentalDecorators: false,\r\n\t\tresolveJsonModule: true,\r\n\t\tskipLibCheck: true,\r\n\t\tlib: ['es2022', 'esnext.decorators']\r\n\t},\r\n\ttranspileOnly: true\r\n});\r\n\r\nrequire('tsconfig-paths').register();\r\n\r\n// Register jsdom globally and set SVGElement on global\r\nrequire('jsdom-global')();\r\n(global as any).SVGElement = (global as any).window.SVGElement;\r\n\r\nhooks('vue').push(function (params: any) {\r\n\ttry {\r\n\t\tconst transformer = new VueTransformer({\r\n\t\t\texclude: ['(?:^|/)node_modules/', '(?:^|/)cucumber-tsflow/lib/']\r\n\t\t});\r\n\t\tconst transformResult = transformer.transformCode(params.content, params.filename);\r\n\r\n\t\treturn transformResult.code;\r\n\t} catch (err) {\r\n\t\tconsole.log(err);\r\n\t}\r\n\treturn params.content;\r\n});\r\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,40 @@
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
+ const hooks = require('require-extension-hooks');
7
+ const vue_sfc_1 = __importDefault(require("../vue-sfc"));
8
+ require('ts-node/esm').register({
9
+ compilerOptions: {
10
+ module: 'nodeNext',
11
+ target: 'es2022',
12
+ strict: true,
13
+ allowJs: true,
14
+ allowSyntheticDefaultImports: true,
15
+ esModuleInterop: true,
16
+ experimentalDecorators: true,
17
+ resolveJsonModule: true,
18
+ skipLibCheck: true,
19
+ lib: ['es2022']
20
+ },
21
+ transpileOnly: true
22
+ });
23
+ require('tsconfig-paths').register();
24
+ // Register jsdom globally and set SVGElement on global
25
+ require('jsdom-global')();
26
+ global.SVGElement = global.window.SVGElement;
27
+ hooks('vue').push(function (params) {
28
+ try {
29
+ const transformer = new vue_sfc_1.default({
30
+ exclude: ['(?:^|/)node_modules/', '(?:^|/)cucumber-tsflow/lib/']
31
+ });
32
+ const transformResult = transformer.transformCode(params.content, params.filename);
33
+ return transformResult.code;
34
+ }
35
+ catch (err) {
36
+ console.log(err);
37
+ }
38
+ return params.content;
39
+ });
40
+ //# sourceMappingURL=tsvue-exp-esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsvue-exp-esm.js","sourceRoot":"","sources":["../../../src/transpilers/esm/tsvue-exp-esm.ts"],"names":[],"mappings":";;;;;AAAA,MAAM,KAAK,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;AACjD,yDAAwC;AAExC,OAAO,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC;IAC/B,eAAe,EAAE;QAChB,MAAM,EAAE,UAAU;QAClB,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,IAAI;QACb,4BAA4B,EAAE,IAAI;QAClC,eAAe,EAAE,IAAI;QACrB,sBAAsB,EAAE,IAAI;QAC5B,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,IAAI;QAClB,GAAG,EAAE,CAAC,QAAQ,CAAC;KACf;IACD,aAAa,EAAE,IAAI;CACnB,CAAC,CAAC;AAEH,OAAO,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,CAAC;AAErC,uDAAuD;AACvD,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;AACzB,MAAc,CAAC,UAAU,GAAI,MAAc,CAAC,MAAM,CAAC,UAAU,CAAC;AAE/D,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,MAAW;IACtC,IAAI,CAAC;QACJ,MAAM,WAAW,GAAG,IAAI,iBAAc,CAAC;YACtC,OAAO,EAAE,CAAC,sBAAsB,EAAE,6BAA6B,CAAC;SAChE,CAAC,CAAC;QACH,MAAM,eAAe,GAAG,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAEnF,OAAO,eAAe,CAAC,IAAI,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC;AACvB,CAAC,CAAC,CAAC","sourcesContent":["const hooks = require('require-extension-hooks');\r\nimport VueTransformer from '../vue-sfc';\r\n\r\nrequire('ts-node/esm').register({\r\n\tcompilerOptions: {\r\n\t\tmodule: 'nodeNext',\r\n\t\ttarget: 'es2022',\r\n\t\tstrict: true,\r\n\t\tallowJs: true,\r\n\t\tallowSyntheticDefaultImports: true,\r\n\t\tesModuleInterop: true,\r\n\t\texperimentalDecorators: true,\r\n\t\tresolveJsonModule: true,\r\n\t\tskipLibCheck: true,\r\n\t\tlib: ['es2022']\r\n\t},\r\n\ttranspileOnly: true\r\n});\r\n\r\nrequire('tsconfig-paths').register();\r\n\r\n// Register jsdom globally and set SVGElement on global\r\nrequire('jsdom-global')();\r\n(global as any).SVGElement = (global as any).window.SVGElement;\r\n\r\nhooks('vue').push(function (params: any) {\r\n\ttry {\r\n\t\tconst transformer = new VueTransformer({\r\n\t\t\texclude: ['(?:^|/)node_modules/', '(?:^|/)cucumber-tsflow/lib/']\r\n\t\t});\r\n\t\tconst transformResult = transformer.transformCode(params.content, params.filename);\r\n\r\n\t\treturn transformResult.code;\r\n\t} catch (err) {\r\n\t\tconsole.log(err);\r\n\t}\r\n\treturn params.content;\r\n});\r\n"]}
@@ -0,0 +1,19 @@
1
+ // lib/transpilers/esm/vue-jsdom-setup.mjs
2
+ /* eslint-disable no-undef */
3
+
4
+ import { createRequire } from 'module';
5
+ const require = createRequire(import.meta.url);
6
+
7
+ require('jsdom-global')();
8
+
9
+ // After jsdom-global, window and document should be global
10
+ // Add Vue-specific constructors to global scope
11
+ if (typeof window !== 'undefined') {
12
+ // Use globalThis for cleaner code
13
+ globalThis.SVGElement = window.SVGElement;
14
+ globalThis.Element = window.Element;
15
+ globalThis.HTMLElement = window.HTMLElement;
16
+ globalThis.HTMLDivElement = window.HTMLDivElement;
17
+ }
18
+
19
+ export {}; // Make it a module