Skip to content

Commit 660c7e8

Browse files
DavertMikclaude
andcommitted
fix: Complete ESM migration and TypeScript definition fixes
- Convert all config files from CommonJS to ESM format - Fix JSDoc generation for ESM codebase - Update runok.cjs to convert ESM imports/exports to CommonJS for JSDoc compatibility - Fix TypeScript definition generation issues - Remove non-existent lib/within.js from JSDoc config - Fix codeceptjs reference in index.d.ts - All pre-commit hooks now pass successfully 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 09063ab commit 660c7e8

15 files changed

+945
-1356
lines changed

docs/helpers/Appium.md

Lines changed: 635 additions & 646 deletions
Large diffs are not rendered by default.

docs/plugins.md

Lines changed: 137 additions & 572 deletions
Large diffs are not rendered by default.

examples/codecept.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
require('./heal_recipes')
1+
import './heal_recipes.js'
22

3-
exports.config = {
3+
export const config = {
44
output: './output',
55
helpers: {
66
Playwright: {

examples/heal_recipes.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
1-
const { heal } = require('../lib/index');
1+
import { heal } from '../lib/index.js'
22

33
heal.addRecipe('clickAndType', {
44
priority: 1,
5-
steps: [
6-
'fillField',
7-
'appendField',
8-
],
5+
steps: ['fillField', 'appendField'],
96
fn: async ({ step }) => {
10-
const locator = step.args[0];
11-
const text = step.args[1];
7+
const locator = step.args[0]
8+
const text = step.args[1]
129

1310
return ({ I }) => {
14-
I.click(locator);
15-
I.wait(1); // to open modal or something
16-
I.type(text);
17-
};
11+
I.click(locator)
12+
I.wait(1) // to open modal or something
13+
I.type(text)
14+
}
1815
},
19-
});
16+
})
2017

2118
// if error X -> send request to service
2219
// if cached -> send request to invalidate cache

prettier.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module.exports = {
1+
export default {
22
printWidth: 220,
33
tabWidth: 2,
44
useTabs: false,

runok.cjs

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ module.exports = {
3737
async defTypings() {
3838
console.log('Generate TypeScript definition')
3939
// Generate definitions for promised-based helper methods
40-
await npx('jsdoc -c typings/jsdocPromiseBased.conf.js')
40+
await npx('jsdoc -c typings/jsdocPromiseBased.conf.json')
4141
fs.renameSync('typings/types.d.ts', 'typings/promiseBasedTypes.d.ts')
4242
// Generate all other regular definitions
43-
await npx('jsdoc -c typings/jsdoc.conf.js')
43+
await npx('jsdoc -c typings/jsdoc.conf.json')
4444
},
4545

4646
async docsPlugins() {
@@ -176,6 +176,31 @@ Our community prepared some valuable recipes for setting up CI systems with Code
176176
cfg.replace(/LocatorOrString/g, 'string | object')
177177
cfg.replace(/CodeceptJS.StringOrSecret/g, 'string | object')
178178
}
179+
// Convert ESM imports to require() for JSDoc compatibility
180+
cfg.replace(/^import\s+([^'"`\s{]+)\s+from\s+['"`]([^'"`]+)['"`]/gm, "const $1 = require('$2')")
181+
cfg.replace(/^import\s*\{\s*([^}]+)\s*\}\s*from\s+['"`]([^'"`]+)['"`]/gm, (match, imports, path) => {
182+
// Handle destructuring imports with aliases - convert to simple require and assign
183+
if (imports.includes(' as ')) {
184+
const parts = imports.split(',').map(i => i.trim())
185+
const assignments = parts.map(part => {
186+
if (part.includes(' as ')) {
187+
const [original, alias] = part.split(' as ').map(s => s.trim())
188+
return `const ${alias} = require('${path}').${original}`
189+
} else {
190+
return `const ${part} = require('${path}').${part}`
191+
}
192+
})
193+
return assignments.join(';\n')
194+
}
195+
return `const { ${imports} } = require('${path}')`
196+
})
197+
cfg.replace(/^import\s+\*\s+as\s+([^'"`]+)\s+from\s+['"`]([^'"`]+)['"`]/gm, "const $1 = require('$2')")
198+
199+
// Convert ESM exports to module.exports for JSDoc compatibility
200+
cfg.replace(/^export\s*\{\s*([^}]+)\s+as\s+default\s*\}/gm, 'module.exports = $1')
201+
cfg.replace(/^export\s+default\s+(.+)/gm, 'module.exports = $1')
202+
cfg.replace(/^export\s*\{\s*([^}]+)\s*\}/gm, 'module.exports = { $1 }')
203+
cfg.replace(/^export\s+(class|function|const|let|var)\s+([^\s=]+)/gm, '$1 $2')
179204
})
180205
}
181206
},
@@ -215,6 +240,32 @@ Our community prepared some valuable recipes for setting up CI systems with Code
215240
cfg.replace(/CodeceptJS.LocatorOrString/g, 'string | object')
216241
cfg.replace(/LocatorOrString/g, 'string | object')
217242
cfg.replace(/CodeceptJS.StringOrSecret/g, 'string | object')
243+
244+
// Convert ESM imports to require() for JSDoc compatibility
245+
cfg.replace(/^import\s+([^'"`\s{]+)\s+from\s+['"`]([^'"`]+)['"`]/gm, "const $1 = require('$2')")
246+
cfg.replace(/^import\s*\{\s*([^}]+)\s*\}\s*from\s+['"`]([^'"`]+)['"`]/gm, (match, imports, path) => {
247+
// Handle destructuring imports with aliases - convert to simple require and assign
248+
if (imports.includes(' as ')) {
249+
const parts = imports.split(',').map(i => i.trim())
250+
const assignments = parts.map(part => {
251+
if (part.includes(' as ')) {
252+
const [original, alias] = part.split(' as ').map(s => s.trim())
253+
return `const ${alias} = require('${path}').${original}`
254+
} else {
255+
return `const ${part} = require('${path}').${part}`
256+
}
257+
})
258+
return assignments.join(';\n')
259+
}
260+
return `const { ${imports} } = require('${path}')`
261+
})
262+
cfg.replace(/^import\s+\*\s+as\s+([^'"`]+)\s+from\s+['"`]([^'"`]+)['"`]/gm, "const $1 = require('$2')")
263+
264+
// Convert ESM exports to module.exports for JSDoc compatibility
265+
cfg.replace(/^export\s*\{\s*([^}]+)\s+as\s+default\s*\}/gm, 'module.exports = $1')
266+
cfg.replace(/^export\s+default\s+(.+)/gm, 'module.exports = $1')
267+
cfg.replace(/^export\s*\{\s*([^}]+)\s*\}/gm, 'module.exports = { $1 }')
268+
cfg.replace(/^export\s+(class|function|const|let|var)\s+([^\s=]+)/gm, '$1 $2')
218269
})
219270

220271
await npx(`documentation build docs/build/${file} -o docs/helpers/${name}.md ${documentjsCliArgs}`)

typings/fixDefFiles.js

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,37 @@
1-
const fs = require('fs');
2-
const { resolve } = require('path');
1+
import fs from 'fs'
2+
import { resolve } from 'path'
33

4-
const filePath = [resolve('./typings/promiseBasedTypes.d.ts'), resolve('./typings/types.d.ts')];
4+
const filePath = [resolve('./typings/promiseBasedTypes.d.ts'), resolve('./typings/types.d.ts')]
55

66
filePath.forEach(file => {
77
fs.readFile(file, 'utf8', (err, data) => {
88
if (err) {
9-
console.error(`Error reading the file: ${err}`);
10-
return;
9+
console.error(`Error reading the file: ${err}`)
10+
return
1111
}
1212

13-
const modifiedContent = modifyContent(data);
13+
const modifiedContent = modifyContent(data)
1414

1515
// Write the modified content back to the file
16-
fs.writeFile(file, modifiedContent, 'utf8', (err) => {
16+
fs.writeFile(file, modifiedContent, 'utf8', err => {
1717
if (err) {
18-
console.error(`Error writing to the file: ${err}`);
19-
return;
18+
console.error(`Error writing to the file: ${err}`)
19+
return
2020
}
2121

22-
console.log(`${file} file is successfully modified and saved.`);
23-
});
24-
});
25-
});
22+
console.log(`${file} file is successfully modified and saved.`)
23+
})
24+
})
25+
})
2626

2727
function modifyContent(content) {
28-
const modifiedContent = content.replace(/ class MockServer {/, ' // @ts-ignore\n'
29-
+ ' class MockServer {').replace(/ type MockServerConfig = {/, ' // @ts-ignore\n'
30-
+ ' type MockServerConfig = {').replace(/ class ExpectHelper {/g, ' // @ts-ignore\n'
31-
+ ' class ExpectHelper {').replace(/ type PlaywrightConfig = {/, ' // @ts-ignore\n'
32-
+ ' type PlaywrightConfig = {').replace(/ type PuppeteerConfig = {/, ' // @ts-ignore\n'
33-
+ ' type PuppeteerConfig = {').replace(/ type RESTConfig = {/, ' // @ts-ignore\n'
34-
+ ' type RESTConfig = {').replace(/ type WebDriverConfig = {/, ' // @ts-ignore\n'
35-
+ ' type WebDriverConfig = {')
36-
return modifiedContent;
28+
const modifiedContent = content
29+
.replace(/ class MockServer {/, ' // @ts-ignore\n' + ' class MockServer {')
30+
.replace(/ type MockServerConfig = {/, ' // @ts-ignore\n' + ' type MockServerConfig = {')
31+
.replace(/ class ExpectHelper {/g, ' // @ts-ignore\n' + ' class ExpectHelper {')
32+
.replace(/ type PlaywrightConfig = {/, ' // @ts-ignore\n' + ' type PlaywrightConfig = {')
33+
.replace(/ type PuppeteerConfig = {/, ' // @ts-ignore\n' + ' type PuppeteerConfig = {')
34+
.replace(/ type RESTConfig = {/, ' // @ts-ignore\n' + ' type RESTConfig = {')
35+
.replace(/ type WebDriverConfig = {/, ' // @ts-ignore\n' + ' type WebDriverConfig = {')
36+
return modifiedContent
3737
}

typings/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ declare const within: typeof CodeceptJS.within
534534
declare const session: typeof CodeceptJS.session
535535
declare const DataTable: typeof CodeceptJS.DataTable
536536
declare const DataTableArgument: typeof CodeceptJS.DataTableArgument
537-
declare const codeceptjs: typeof CodeceptJS.index
537+
declare const codeceptjs: typeof CodeceptJS
538538
declare const locate: typeof CodeceptJS.Locator.build
539539
declare function inject(): CodeceptJS.SupportObject
540540
declare function inject<T extends keyof CodeceptJS.SupportObject>(name: T): CodeceptJS.SupportObject[T]

typings/jsdoc.conf.js

Lines changed: 0 additions & 42 deletions
This file was deleted.

typings/jsdoc.conf.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"source": {
3+
"include": [
4+
"./docs/build",
5+
"./lib/actor.js",
6+
"./lib/codecept.js",
7+
"./lib/config.js",
8+
"./lib/result.js",
9+
"./lib/container.js",
10+
"./lib/data/table.js",
11+
"./lib/data/dataTableArgument.js",
12+
"./lib/effects.js",
13+
"./lib/event.js",
14+
"./lib/index.js",
15+
"./lib/locator.js",
16+
"./lib/output.js",
17+
"./lib/pause.js",
18+
"./lib/recorder.js",
19+
"./lib/secret.js",
20+
"./lib/session.js",
21+
"./lib/step/config.js",
22+
"./lib/step/base.js",
23+
"./lib/step/helper.js",
24+
"./lib/step/meta.js",
25+
"./lib/store.js",
26+
"./lib/mocha/ui.js",
27+
"./lib/mocha/featureConfig.js",
28+
"./lib/mocha/scenarioConfig.js",
29+
"./lib/mocha/bdd.js",
30+
"./lib/mocha/hooks.js",
31+
"./node_modules/@codeceptjs/detox-helper/Detox.js",
32+
"./node_modules/@codeceptjs/helper/dist/index.js"
33+
]
34+
},
35+
"opts": {
36+
"template": "node_modules/tsd-jsdoc/dist",
37+
"recurse": true,
38+
"destination": "./typings/"
39+
},
40+
"plugins": ["jsdoc.namespace.cjs", "jsdoc-typeof-plugin"]
41+
}

0 commit comments

Comments
 (0)