codemod 0.0.4 → 0.8.0-rc1

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/package.json CHANGED
@@ -1,24 +1,93 @@
1
1
  {
2
2
  "name": "codemod",
3
- "version": "0.0.4",
4
- "description": "Utilities for modifying your code with code",
5
- "main": "index.js",
6
- "scripts": {
7
- "test": "jest"
3
+ "version": "0.8.0-rc1",
4
+ "description": "A codemod engine for Node.js libraries (jscodeshift, ts-morph, etc.)",
5
+ "type": "module",
6
+ "exports": null,
7
+ "repository": {
8
+ "type": "git"
8
9
  },
9
10
  "keywords": [
10
- "codemod"
11
+ "codemod",
12
+ "jscodeshift",
13
+ "ts-morph",
14
+ "refactor",
15
+ "transform",
16
+ "cli",
17
+ "dependencies",
18
+ "migrate",
19
+ "eslint",
20
+ "prettier",
21
+ "progress",
22
+ "AST",
23
+ "next.js",
24
+ "ember",
25
+ "react"
26
+ ],
27
+ "main": "./dist/index.cjs",
28
+ "bin": "./dist/index.cjs",
29
+ "devDependencies": {
30
+ "@babel/core": "^7.20.2",
31
+ "@babel/parser": "^7.22.10",
32
+ "@babel/preset-env": "^7.20.2",
33
+ "@babel/traverse": "7.23.2",
34
+ "@effect/schema": "0.27.0",
35
+ "@svgr/hast-util-to-babel-ast": "^7.0.0",
36
+ "applicationinsights": "^2.9.1",
37
+ "ast-types": "^0.14.2",
38
+ "axios": "^1.4.0",
39
+ "cosmiconfig": "^8.3.6",
40
+ "form-data": "^4.0.0",
41
+ "fast-glob": "3.3.2",
42
+ "jscodeshift": "^0.14.0",
43
+ "mdast-util-from-markdown": "^2.0.0",
44
+ "mdast-util-mdx": "^3.0.0",
45
+ "mdast-util-to-markdown": "^2.1.0",
46
+ "memfs": "^4.2.0",
47
+ "micromark-extension-mdxjs": "^2.0.0",
48
+ "minimatch": "^9.0.3",
49
+ "rehype-parse": "^8.0.4",
50
+ "tar": "^6.1.15",
51
+ "terminal-link": "^3.0.0",
52
+ "ts-morph": "18.0.0",
53
+ "unified": "^10.1.2",
54
+ "unist-util-filter": "^5.0.1",
55
+ "unist-util-visit": "^5.0.0",
56
+ "valibot": "^0.24.1",
57
+ "yargs": "^17.6.2",
58
+ "@types/babel__traverse": "^7.20.1",
59
+ "@types/jscodeshift": "^0.11.5",
60
+ "@types/node": "18.11.9",
61
+ "@types/sinon": "^10.0.20",
62
+ "@types/tar": "^6.1.5",
63
+ "@types/yargs": "^17.0.13",
64
+ "@vitest/coverage-v8": "^1.0.1",
65
+ "esbuild": "^0.17.14",
66
+ "sinon": "^17.0.0",
67
+ "ts-node": "^10.9.1",
68
+ "typescript": "5.2.2",
69
+ "vitest": "^1.0.1",
70
+ "@codemod-com/filemod": "2.0.2",
71
+ "@codemod-com/utilities": "1.1.0"
72
+ },
73
+ "packageManager": "pnpm@8.6.7",
74
+ "pkg": {
75
+ "outputPath": "./package/"
76
+ },
77
+ "author": "Caartaa, Inc.",
78
+ "license": "Apache License, Version 2.0",
79
+ "files": [
80
+ "./dist/index.cjs",
81
+ "LICENSE",
82
+ "README.md"
11
83
  ],
12
- "author": "Jahred Hope <jahredhope@gmail.com>",
13
- "license": "ISC",
14
- "dependencies": {
15
- "babylon": "^6.16.1",
16
- "camelcase": "^4.0.0",
17
- "eslint": "^3.17.0",
18
- "eslint-plugin-import": "^2.2.0",
19
- "jest": "^19.0.2",
20
- "prettier": "^0.21.0",
21
- "recursive-readdir": "^2.1.1",
22
- "some-values": "^0.0.1"
84
+ "publishConfig": {
85
+ "access": "public"
86
+ },
87
+ "scripts": {
88
+ "build": "esbuild ./src/index.ts --define:__CODEMODCOM_CLI_VERSION__=\\\"0.8.0-rc1\\\" --bundle --platform=node --target=node16 --minify --format=cjs --legal-comments=inline --outfile=./dist/index.cjs",
89
+ "package": "pkg --compress GZip .",
90
+ "test": "TEST=1 vitest run",
91
+ "coverage": "TEST=1 vitest run --coverage"
23
92
  }
24
- }
93
+ }
package/.eslintrc.js DELETED
@@ -1,30 +0,0 @@
1
- module.exports = {
2
- "env": {
3
- "es6": true,
4
- "node": true,
5
- "jest": true
6
- },
7
- "extends": "eslint:recommended",
8
- "parserOptions": {
9
- "sourceType": "module"
10
- },
11
- "rules": {
12
- "indent": [
13
- "error",
14
- 2
15
- ],
16
- "linebreak-style": [
17
- "error",
18
- "unix"
19
- ],
20
- "quotes": [
21
- "error",
22
- "single"
23
- ],
24
- "semi": [
25
- "error",
26
- "never"
27
- ],
28
- "no-console": 0
29
- }
30
- };
package/.npmignore DELETED
@@ -1,2 +0,0 @@
1
- node_modules
2
- .git
package/.travis.yml DELETED
@@ -1,4 +0,0 @@
1
- language: node_js
2
- node_js:
3
- - "7"
4
- cache: yarn
@@ -1,21 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`formatWithImports render with imports 1`] = `
4
- "const aVar = require('./aVar');
5
- const bVar = require('./bVar');
6
-
7
- require('./nameless');
8
-
9
- window.cVar = require('./cVar');
10
-
11
- initial
12
- content"
13
- `;
14
-
15
- exports[`formatWithImports should remove duplicate includes 1`] = `
16
- "const aVar = require('./aVar');
17
- const bVar = require('./bVar');
18
-
19
- initial
20
- content"
21
- `;
package/clean.js DELETED
@@ -1,31 +0,0 @@
1
- const { log, writeLog } = require('./logger')
2
- const findFilesWith = require('./findFilesWith')
3
-
4
- const { readFile, writeFile } = require('./file')
5
- const babylon = require('babylon')
6
-
7
- const parse = (contents) => babylon.parse(contents, {
8
- plugins: ['objectRestSpread']
9
- })
10
-
11
- const print = require('./print')
12
-
13
- log('Cleaning all files')
14
-
15
- module.exports = (rootDir) => findFilesWith(rootDir, /\.js$/)
16
- .then(fileNames => {
17
- fileNames.map(fileName => {
18
- const contents = readFile(fileName)
19
- // const tree = parse(contents)
20
- writeFile(fileName, print(contents))
21
- return fileName
22
- })
23
- })
24
- .then(fileNames => {
25
- if (fileNames && fileNames.length) {
26
- writeLog(`Cleaned ${fileNames.length} files`)
27
- } else {
28
- writeLog('No files cleaned')
29
- }
30
-
31
- })
package/encodeRegex.js DELETED
@@ -1,6 +0,0 @@
1
- module.exports = (txt) => {
2
- if (typeof txt !== 'string') {
3
- throw new TypeError(`Unable to encode value of type ${typeof txt}`)
4
- }
5
- return txt && txt.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
6
- }
package/file.js DELETED
@@ -1,14 +0,0 @@
1
- const fs = require('fs')
2
-
3
- const { log } = require('./logger')
4
-
5
- function writeFile(file, content) {
6
- log('write file', file, content.length)
7
- fs.writeFileSync(file, content)
8
- }
9
-
10
- function readFile(file) {
11
- return fs.readFileSync(file, 'utf8')
12
- }
13
-
14
- module.exports = { writeFile, readFile }
package/file.test.js DELETED
@@ -1,55 +0,0 @@
1
- const file = require('./file')
2
-
3
- jest.mock('fs')
4
-
5
- const fs = require('fs')
6
-
7
- describe('File wrapper', () => {
8
- describe('writer', () => {
9
- beforeEach(() => {
10
- fs.writeFileSync.mockReset()
11
- })
12
- it('should write a file when writeFile called', () => {
13
- file.writeFile('example.file', 'example content')
14
-
15
- expect(fs.writeFileSync).toHaveBeenCalled()
16
- })
17
- it('should write a file for each file', () => {
18
- file.writeFile('example1.file', 'example content')
19
- file.writeFile('example2.file', 'example content')
20
-
21
- expect(fs.writeFileSync).toHaveBeenCalledTimes(2)
22
- })
23
- it('should write a file with given file name', () => {
24
- const fileName = 'example.file'
25
- const content = 'example content'
26
-
27
- file.writeFile(fileName, content)
28
-
29
- expect(fs.writeFileSync).toHaveBeenCalledWith(fileName, content)
30
- })
31
-
32
- })
33
- describe('reader', () => {
34
- beforeEach(() => {
35
- fs.readFileSync.mockReset()
36
- })
37
- it('should read a file when readFile called', () => {
38
- file.readFile('example.file')
39
-
40
- expect(fs.readFileSync).toHaveBeenCalled()
41
- })
42
- it('should read a file as utf8', () => {
43
- file.readFile('example.file')
44
-
45
- expect(fs.readFileSync).toHaveBeenCalledWith('example.file', 'utf8')
46
- })
47
- it('should multiple files', () => {
48
- file.readFile('example1.file')
49
- file.readFile('example2.file')
50
-
51
- expect(fs.readFileSync).toHaveBeenCalledTimes(2)
52
- })
53
-
54
- })
55
- })
package/findFilesWith.js DELETED
@@ -1,19 +0,0 @@
1
- const recursive = require('recursive-readdir')
2
- const fs = require('fs')
3
-
4
- module.exports = function findFilesWith(rootDir, fileRegex, contentRegex) {
5
- return new Promise((resolve, reject) => {
6
- const ignoreFunc = (file, stats) => fileRegex && !stats.isDirectory() && !file.match(fileRegex)
7
- recursive(rootDir, [ignoreFunc], (err, files) => {
8
- if (err) {
9
- return reject(err)
10
- }
11
- return contentRegex
12
- ? resolve(files.filter(file => {
13
- const contents = fs.readFileSync(file, 'utf8')
14
- return contents.match(contentRegex)
15
- }))
16
- : resolve(files)
17
- })
18
- })
19
- }
@@ -1,122 +0,0 @@
1
- /*
2
- * Renders a file by first adding any imports given that don't already exist
3
- */
4
-
5
- const regexNamedImport = /(?:\n|^) *const (\w{3,50}) = require\(["']([^'"]+)["']\);?/g
6
- const regexNamelessImport = /(?:\n|^) *require\(["']([^'"]+)["']\);?/g
7
- const regexGlobalImport = /(?:\n|^) *window.(\w{3,50}) = require\(["']([^'"]+)["']\);?/g
8
-
9
- module.exports = ({
10
- content,
11
- imports, // Deprecated
12
- namedImports,
13
- namelessImports,
14
- globalImports
15
- }, options = {}) => {
16
-
17
- let newContent
18
- const existingNamedImports = {}
19
- const existingNamelessImports = new Set()
20
- const existingGlobalImports = {}
21
-
22
- if (typeof content !== 'string') {
23
- throw new TypeError('Must contain intial content')
24
- }
25
-
26
- if (typeof options === 'boolean') {
27
- console.warn('DEPRECATED: Third parameter is object field. Use { replaceOld: true }')
28
- options = {replaceOld: options}
29
- }
30
- if (typeof imports !== 'undefined') {
31
- console.warn('DEPRECATED: imports has been renamed to namedImports')
32
- if (!namedImports) {
33
- namedImports = imports
34
- }
35
- }
36
-
37
- newContent = content
38
-
39
- newContent = newContent.replace(regexNamelessImport, (match, importDirectory) => {
40
- existingNamelessImports.add(importDirectory)
41
- return ''
42
- })
43
-
44
- newContent = newContent.replace(regexNamedImport, (match, importName, importDirectory) => {
45
- existingNamedImports[importName] = importDirectory
46
- return ''
47
- })
48
-
49
- newContent = newContent.replace(regexGlobalImport, (match, importName, importDirectory) => {
50
- existingGlobalImports[importName] = importDirectory
51
- return ''
52
- })
53
-
54
-
55
- // Clear newlines from the start of file
56
- newContent = newContent.replace(/^\n*/, '')
57
-
58
- // Combine or replace with new imports
59
- const newNamedImports = {}
60
- const newNamelessImports = existingNamelessImports
61
- const newGlobalImports = {}
62
-
63
- if (namelessImports) {
64
- namelessImports.forEach((namelessImport => { newNamelessImports.add(namelessImport) }))
65
- }
66
- if (!options.replaceOld) {
67
- Object.assign(newNamedImports, existingNamedImports)
68
- Object.assign(newGlobalImports, existingGlobalImports)
69
- }
70
- Object.assign(newNamedImports, namedImports)
71
- Object.assign(newGlobalImports, globalImports)
72
-
73
- if (newNamelessImports) {
74
- // Clear nameless imports that are imported elsewhere
75
- Object.values(newNamedImports)
76
- .forEach(importLocation => {
77
- newNamelessImports.delete(importLocation)
78
- })
79
-
80
- Object.values(newGlobalImports)
81
- .forEach(importLocation => {
82
- newNamelessImports.delete(importLocation)
83
- })
84
- }
85
-
86
- // Add named imports to newContent
87
- const namedImportsAsString = Object.entries(newNamedImports)
88
- .sort(([importNameA], [importNameB]) => importNameA.localeCompare(importNameB))
89
- .map(([importName, importDirectory]) => `const ${importName} = require('${importDirectory}');`)
90
- .join('\n')
91
-
92
-
93
- // Add nameless imports to newContent
94
- const namelessImportsAsString = Array.from(newNamelessImports)
95
- .sort()
96
- .map(importDirectory => `require('${importDirectory}');`)
97
- .join('\n')
98
-
99
- // Add imports to newContent
100
- const globalImportsAsString = Object.entries(newGlobalImports)
101
- .sort(([importNameA], [importNameB]) => importNameA.localeCompare(importNameB))
102
- .map(([importName, importDirectory]) => `window.${importName} = require('${importDirectory}');`)
103
- .join('\n')
104
-
105
- const contentArray = []
106
-
107
- if (namedImportsAsString) {
108
- contentArray.push(namedImportsAsString)
109
- }
110
-
111
- if (namelessImportsAsString) {
112
- contentArray.push(namelessImportsAsString)
113
- }
114
-
115
- if (globalImportsAsString) {
116
- contentArray.push(globalImportsAsString)
117
- }
118
-
119
- contentArray.push(newContent)
120
-
121
- return contentArray.join('\n\n')
122
- }
@@ -1,61 +0,0 @@
1
- let formatWithImports = require('./formatWithImports')
2
-
3
- jest.mock('./file')
4
-
5
- const file = require('./file')
6
-
7
- describe('formatWithImports', () => {
8
- beforeEach(() => {
9
- file.writeFile.mockReset()
10
- })
11
-
12
- it('should export a function', () => {
13
- expect(typeof formatWithImports).toBe('function')
14
- })
15
-
16
- it('should require contents', () => {
17
- expect(() => formatWithImports('', {})).toThrow(TypeError)
18
- })
19
-
20
- it('should return a string', () => {
21
- const result = formatWithImports({content: 'initial content'})
22
-
23
- expect(typeof result).toBe('string')
24
- })
25
-
26
- it('should not change content', () => {
27
- let content = 'initial content'
28
- const result = formatWithImports({content: content})
29
-
30
- expect(result).toBe(content)
31
- })
32
-
33
- it('should strip initial whitespace', () => {
34
- let content = 'initial content'
35
- const result = formatWithImports({content: '\n\n\n'+content})
36
-
37
- expect(result).toBe(content)
38
- })
39
-
40
- it('render with imports', () => {
41
- let content = 'initial\ncontent'
42
- const result = formatWithImports({
43
- content: content,
44
- namedImports: {aVar: './aVar', bVar: './bVar'},
45
- namelessImports: ['./nameless'],
46
- globalImports: {cVar: './cVar'}
47
- })
48
- expect(result).toMatchSnapshot()
49
- })
50
-
51
- it('should remove duplicate includes', () => {
52
- let content = 'initial\ncontent'
53
- const result = formatWithImports({
54
- content: content,
55
- namedImports: {aVar: './aVar', bVar: './bVar'},
56
- namelessImports: ['./aVar']
57
- })
58
- expect(result).toMatchSnapshot()
59
-
60
- })
61
- })
package/index.js DELETED
@@ -1,21 +0,0 @@
1
- const { writeFile, readFile } = require('./file')
2
- const writeFileWithImports = require('./writeFileWithImports')
3
- const findFilesWith = require('./findFilesWith')
4
- const {log, writeLog} = require('./logger')
5
- const camelCase = require('camelcase')
6
- const print = require('./print')
7
- const clean = require('./clean')
8
- const encodeRegex = require('./encodeRegex')
9
-
10
- module.exports = {
11
- writeFileWithImports,
12
- writeFile,
13
- readFile,
14
- findFilesWith,
15
- log,
16
- writeLog,
17
- camelCase,
18
- print,
19
- clean,
20
- encodeRegex
21
- }
package/logger.js DELETED
@@ -1,17 +0,0 @@
1
- const fs = require('fs')
2
- const path = require('path')
3
-
4
- let logOutput = []
5
-
6
- let reportFileLocation = path.join(process.cwd(), 'output.log')
7
- function log(...args) {
8
- logOutput.push(args.join(' '))
9
- }
10
- function writeLog(...args) {
11
- log(...args)
12
- console.log(...args)
13
- console.log('writing log to', reportFileLocation)
14
- fs.writeFileSync(reportFileLocation, logOutput.join('\n'))
15
- }
16
-
17
- module.exports = { log, writeLog, reportFileLocation }
package/logger.test.js DELETED
@@ -1,23 +0,0 @@
1
- const logger = require('./logger')
2
-
3
- jest.mock('fs')
4
-
5
- describe('logger', () => {
6
- let oldLog
7
-
8
- beforeAll(() => {
9
- oldLog = global.console.log
10
- global.console.log = jest.fn()
11
- })
12
- afterAll(() => {
13
- global.console.log = oldLog
14
- })
15
-
16
- it('should export two functions', () => {
17
- expect(logger.log).toBeDefined()
18
- expect(logger.writeLog).toBeDefined()
19
- })
20
- it('should have a default report location', () => {
21
- expect(logger.reportFileLocation).toContain('/output.log')
22
- })
23
- })
package/print.js DELETED
@@ -1,29 +0,0 @@
1
- /* eslint-disable */
2
- const prettier = require("prettier");
3
-
4
- module.exports = (source) => prettier.format(source, {
5
- // Fit code within this line limit
6
- printWidth: 180,
7
-
8
- // Number of spaces it should use per tab
9
- tabWidth: 4,
10
-
11
- // If true, will use single instead of double quotes
12
- singleQuote: true,
13
-
14
- // Controls the printing of trailing commas wherever possible. Valid options:
15
- // "none" - No trailing commas
16
- // "es5" - Trailing commas where valid in ES5 (objects, arrays, etc)
17
- // "all" - Trailing commas wherever possible (function arguments)
18
- trailingComma: 'none',
19
-
20
- // Controls the printing of spaces inside object literals
21
- bracketSpacing: true,
22
-
23
- // If true, puts the `>` of a multi-line jsx element at the end of
24
- // the last line instead of being alone on the next line
25
- jsxBracketSameLine: false,
26
-
27
- // Which parser to use. Valid options are 'flow' and 'babylon'
28
- parser: 'babylon'
29
- });
@@ -1,12 +0,0 @@
1
- /*
2
- * Writes a file to the filesystem by first adding any imports given that don't already exist
3
- */
4
-
5
- const { writeFile } = require('./file')
6
- const formatWithImports = require('./formatWithImports')
7
-
8
- module.exports = (fileName, fileContentsObject, options = {}) => {
9
-
10
- const newContent = formatWithImports(fileContentsObject, options)
11
- writeFile(fileName, newContent)
12
- }
@@ -1,25 +0,0 @@
1
- let writeFileWithImports = require('./writeFileWithImports')
2
-
3
- jest.mock('./file')
4
-
5
- const file = require('./file')
6
-
7
- describe('writeFileWithImports', () => {
8
- beforeEach(() => {
9
- file.writeFile.mockReset()
10
- })
11
-
12
- it('should export a function', () => {
13
- expect(typeof writeFileWithImports).toBe('function')
14
- })
15
-
16
- it('should require contents', () => {
17
- expect(() => writeFileWithImports('', {})).toThrow(TypeError)
18
- })
19
-
20
- it('should write a file', () => {
21
- writeFileWithImports('example.file', {content: 'initial content'})
22
-
23
- expect(file.writeFile).toHaveBeenCalled()
24
- })
25
- })