Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions codemods/camelcase-sendfile/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Migrate legacy `res.sendfile(file)` to `res.sendFile(file)`

Migrates usage of the legacy APIs `res.sendfile(file)` to `res.sendFile(file)`.

## Example

### Migrating `res.sendfile(file)`

The migration involves replacing instances of `res.sendfile(file)` with `res.sendFile(file)`.

```diff
app.get('/some-route', (req, res) => {
// Some logic here
- res.sendfile('/path/to/file');
+ res.sendFile('/path/to/file');
});
```

## References

- [Migration of res.sendfile(file)](https://expressjs.com/en/guide/migrating-5.html#res.sendFile)
24 changes: 24 additions & 0 deletions codemods/camelcase-sendfile/codemod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
schema_version: "1.0"
name: "@expressjs/camelcase-sendfile"
version: "1.0.0"
description: Migrates usage of the legacy API `res.sendfile(file)` to `res.sendFile(file)`
author: bjohansebas (Sebastian Beltran)
license: MIT
workflow: workflow.yaml
category: migration

targets:
languages:
- javascript
- typescript

keywords:
- transformation
- migration
- express
- sendFile
- files

registry:
access: public
visibility: public
22 changes: 22 additions & 0 deletions codemods/camelcase-sendfile/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@expressjs/camelcase-sendfile",
"private": true,
"version": "1.0.0",
"description": "Migrates usage of the legacy API `res.sendfile(file)` to `res.sendFile(file)`.",
"type": "module",
"scripts": {
"test": "npx codemod jssg test -l typescript ./src/workflow.ts ./"
},
"repository": {
"type": "git",
"url": "git+https://github.com/expressjs/codemod.git",
"directory": "codemods/camelcase-sendfile",
"bugs": "https://github.com/expressjs/codemod/issues"
},
"author": "bjohansebas (Sebastian Beltran)",
"license": "MIT",
"homepage": "https://github.com/expressjs/codemod/blob/main/codemods/camelcase-sendfile/README.md",
"devDependencies": {
"@codemod.com/jssg-types": "^1.3.1"
}
}
33 changes: 33 additions & 0 deletions codemods/camelcase-sendfile/src/workflow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type Js from '@codemod.com/jssg-types/src/langs/javascript'
import type { Edit, SgRoot } from '@codemod.com/jssg-types/src/main'

async function transform(root: SgRoot<Js>): Promise<string | null> {
const rootNode = root.root()

const nodes = rootNode.findAll({
rule: {
pattern: '$OBJ.$METHOD($$$METHOD)',
},
constraints: {
METHOD: { regex: '^(sendfile)$' },
},
})

const edits: Edit[] = []

for (const call of nodes) {
const method = call.getMatch('METHOD')
const obj = call.getMatch('OBJ')
if (!method || !obj) continue

const objDef = obj.definition({ resolveExternal: false })
if (!objDef) continue

edits.push(method.replace('sendFile'))
}

if (edits.length === 0) return null
return rootNode.commitEdits(edits)
}

export default transform
67 changes: 67 additions & 0 deletions codemods/camelcase-sendfile/tests/expected/send-file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import express from "express";
import path from "path";
import sendfile from "other-place"

const app = express();
const options = {
root: path.join(__dirname, 'public'),
dotfiles: 'deny',
headers: {
'x-timestamp': Date.now(),
'x-sent': true
}
}

const sharedSendFile = (res, next, fileName) => {
res.sendFile(fileName, options, (err) => {
if (err) {
next(err)
} else {
console.log('Sent:', fileName)
}
})
}

app.get('/file/:name', (req, res, next) => {
res.sendFile()
})

app.get('/file/:name', (req, res, next) => {
res.sendFile("file.txt")
})

app.get('/file/:name', (req, res, next) => {
const fileName = req.params.name

res.sendFile(fileName, options, (err) => {
if (err) {
next(err)
} else {
console.log('Sent:', fileName)
}
})
sharedSendFile(res, next, fileName);
})

app.get('/filename/:name', function (req, res, next) {
const fileName = req.params.name

res.sendFile(fileName, options, (err) => {
if (err) {
next(err)
} else {
console.log('Sent:', fileName)
}
})
sharedSendFile(res, next, fileName);
})

app.get('/file-handler', (req, res, next) => {
sendfile('test', options, (err) => {
if (err) {
next(err)
} else {
console.log('Sent:', 'test')
}
})
})
67 changes: 67 additions & 0 deletions codemods/camelcase-sendfile/tests/input/send-file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import express from "express";
import path from "path";
import sendfile from "other-place"

const app = express();
const options = {
root: path.join(__dirname, 'public'),
dotfiles: 'deny',
headers: {
'x-timestamp': Date.now(),
'x-sent': true
}
}

const sharedSendFile = (res, next, fileName) => {
res.sendfile(fileName, options, (err) => {
if (err) {
next(err)
} else {
console.log('Sent:', fileName)
}
})
}

app.get('/file/:name', (req, res, next) => {
res.sendfile()
})

app.get('/file/:name', (req, res, next) => {
res.sendfile("file.txt")
})

app.get('/file/:name', (req, res, next) => {
const fileName = req.params.name

res.sendfile(fileName, options, (err) => {
if (err) {
next(err)
} else {
console.log('Sent:', fileName)
}
})
sharedSendFile(res, next, fileName);
})

app.get('/filename/:name', function (req, res, next) {
const fileName = req.params.name

res.sendfile(fileName, options, (err) => {
if (err) {
next(err)
} else {
console.log('Sent:', fileName)
}
})
sharedSendFile(res, next, fileName);
})

app.get('/file-handler', (req, res, next) => {
sendfile('test', options, (err) => {
if (err) {
next(err)
} else {
console.log('Sent:', 'test')
}
})
})
28 changes: 28 additions & 0 deletions codemods/camelcase-sendfile/workflow.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/codemod-com/codemod/refs/heads/main/schemas/workflow.json

version: "1"

nodes:
- id: apply-transforms
name: Apply AST Transformations
type: automatic
runtime:
type: direct
steps:
- name: Migrates usage of the legacy APIs `res.sendfile(file)` to `res.sendFile(file)`
js-ast-grep:
js_file: src/workflow.ts
base_path: .
semantic_analysis: file
include:
- "**/*.cjs"
- "**/*.js"
- "**/*.jsx"
- "**/*.mjs"
- "**/*.cts"
- "**/*.mts"
- "**/*.ts"
- "**/*.tsx"
exclude:
- "**/node_modules/**"
language: typescript
12 changes: 12 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.