Skip to content
Merged
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/route-del-to-delete/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Migrate legacy `app.del()` to `app.delete()`

Migrates usage of the legacy APIs `app.del()` to `app.delete()`.
Initially, `del` was used instead of `delete`, because `delete` is a reserved keyword in JavaScript. However, as of ECMAScript 6, `delete` and other reserved keywords can legally be used as property names. The `app.del()` method was deprecated in Express 4 and removed in Express 5.

## Example

### Migrating `app.del()`

The migration involves replacing instances of `app.del()` with `app.delete()`.

```diff
- app.del('/some-route', (req, res) => {
+ app.delete('/some-route', (req, res) => {
// Some logic here
});
```

## References

- [Migration of app.del()](https://expressjs.com/en/guide/migrating-5.html#app.del)
25 changes: 25 additions & 0 deletions codemods/route-del-to-delete/codemod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
schema_version: "1.0"
name: "@expressjs/route-del-to-delete"
version: "1.0.0"
description: Migrates usage of the legacy APIs `app.del()` to `app.delete()`
author: bjohansebas (Sebastian Beltran)
license: MIT
workflow: workflow.yaml
repository: "https://github.com/expressjs/codemod/tree/HEAD/codemods/route-del-to-delete"
category: migration

targets:
languages:
- javascript
- typescript

keywords:
- transformation
- migration
- express
- redirect
- location

registry:
access: public
visibility: public
22 changes: 22 additions & 0 deletions codemods/route-del-to-delete/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@expressjs/route-del-to-delete",
"private": true,
"version": "1.0.0",
"description": "Migrates usage of the legacy APIs `app.del` to `app.delete`.",
"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/route-del-to-delete",
"bugs": "https://github.com/expressjs/codemod/issues"
},
"author": "bjohansebas (Sebastian Beltran)",
"license": "MIT",
"homepage": "https://github.com/expressjs/codemod/blob/main/codemods/route-del-to-delete/README.md",
"devDependencies": {
"@codemod.com/jssg-types": "^1.3.1"
}
}
43 changes: 43 additions & 0 deletions codemods/route-del-to-delete/src/workflow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
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($$$ARG)',
},
constraints: {
METHOD: { regex: '^(del)$' },
},
})

if (!nodes.length) return null

const edits: Edit[] = []

for (const call of nodes) {
const method = call.getMatch('METHOD')
const args = call.getMultipleMatches('ARG')
if (!method) continue

// $$$ARG yields argument nodes interleaved with separators, so arg nodes are at 0,2,4...
const first = args[0]
if (!first) continue

const isString = first.is('string')
const isRegexp = first.is('regexp') || first.is('regex') || first.is('regular_expression')
const isArray = first.is('array') || first.is('array_expression')

if (!isString && !isRegexp && !isArray) continue

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

if (!edits.length) return null

return rootNode.commitEdits(edits)
}

export default transform
39 changes: 39 additions & 0 deletions codemods/route-del-to-delete/tests/expected/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import express from "express";

const app = express();

app.get("/", (req, res) => {});

app.delete([""],() => {
myImportantLogic();
});

app.delete([],() => {
myImportantLogic();
});

app.delete(/d/,() => {
myImportantLogic();
});

app.del(() => {
myImportantLogic();
});

app.del(function () {
myImportantLogic();
});

app.delete("/old", () => {
myImportantLogic();
});

function noModify() {
let a

app.del(a)
}

const myImportantLogic = () => {
console.log("making sure it's there");
};
39 changes: 39 additions & 0 deletions codemods/route-del-to-delete/tests/input/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import express from "express";

const app = express();

app.get("/", (req, res) => {});

app.del([""],() => {
myImportantLogic();
});

app.del([],() => {
myImportantLogic();
});

app.del(/d/,() => {
myImportantLogic();
});

app.del(() => {
myImportantLogic();
});

app.del(function () {
myImportantLogic();
});

app.del("/old", () => {
myImportantLogic();
});

function noModify() {
let a

app.del(a)
}

const myImportantLogic = () => {
console.log("making sure it's there");
};
28 changes: 28 additions & 0 deletions codemods/route-del-to-delete/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 `app.del()` to `app.delete()`
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.

Loading