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
4 changes: 2 additions & 2 deletions packages/ast/src/types/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ export interface FsContext extends TransformContext {
}

export interface AstCliContext extends FsContext {
warn(node: NodePath<AstNode> | null, message: string): void;
fail(node: NodePath<AstNode> | null, message: string): void;
warn(node: NodePath<AstNode> | Error | null, message: string): void;
fail(node: NodePath<AstNode> | Error | null, message: string): void;
}

export type AstTransformResult = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import j, { Collection } from 'jscodeshift';
import { AstCliContext, AstTransform, NodePath } from '@ag-grid-devtools/ast';
import { AstCliContext, AstTransform, NodePath, Node } from '@ag-grid-devtools/ast';

export type JSCodeShiftTransformer = (root: Collection) => void | any;
export type ErrorSpec = { path: j.ASTPath<j.Node>; message: string };

export type JSCodeShiftTransformer = (root: Collection) => void | {
errors: ErrorSpec[];
warnings: ErrorSpec[];
};

// Use https://astexplorer.net/ to iterate on your transformer
// Parser: Typescript
Expand All @@ -15,11 +20,16 @@ export type JSCodeShiftTransformer = (root: Collection) => void | any;
export const jsCodeShiftTransform = (
...transforms: JSCodeShiftTransformer[]
): AstTransform<AstCliContext> => {
const errors: Error[] = [];
const warnings: Error[] = [];
let source: any;

return (_babel) => ({
visitor: {
Program: {
exit(path: NodePath) {
const root: Collection<any> = j((path.hub as any).file.ast);
source = (path.hub as any).file.ast;
const root: Collection<any> = j(source);
const getFirstNode = () => root.find(j.Program).get('body', 0).node;

// save initial comment if any
Expand All @@ -28,7 +38,21 @@ export const jsCodeShiftTransform = (

// transform
for (const transform of transforms) {
transform(root);
const result = transform(root);
if (result?.errors) {
errors.push(
...result.errors.map((error) =>
path.hub.buildError(error.path.node as Node, error.message),
),
);
}
if (result?.warnings) {
warnings.push(
...result.warnings.map((warning) =>
path.hub.buildError(warning.path.node as Node, warning.message),
),
);
}
}

// restore initial comment if any
Expand All @@ -43,5 +67,14 @@ export const jsCodeShiftTransform = (
},
},
},
post(_file) {
for (const warning of warnings) {
this.opts.warn(warning, warning.message);
}

for (const error of errors) {
this.opts.fail(error, error.message);
}
},
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const packageLicenseManager: JSCodeShiftTransformer = (root) => {

if (alreadyExists) {
// This package file already has a ModuleRegistry import so looks like it has already been transformed
return root.toSource();
return;
}

const usingCharts: UsingCharts = process.env.AG_USING_CHARTS as any;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { JSCodeShiftTransformer } from '../../../plugins/jscodeshift';
const chartTypeKeys = ['area', 'bar', 'column', 'line'];

// find [chart-type] keys, and merge their contents into the parent object
export const chartTypeSubobject: JSCodeShiftTransformer = (root) =>
export const chartTypeSubobject: JSCodeShiftTransformer = (root) => {
root
.find(j.ObjectProperty, { key: { name: 'cellRendererParams' } })
.find(j.ObjectProperty, { key: { name: 'sparklineOptions' } })
Expand All @@ -17,3 +17,4 @@ export const chartTypeSubobject: JSCodeShiftTransformer = (root) =>
});
path.replace();
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import j from 'jscodeshift';
import { JSCodeShiftTransformer } from '../../../plugins/jscodeshift';

// update bar/column types to bar with matching direction
export const columnToVerticalBarTransform: JSCodeShiftTransformer = (root) =>
export const columnToVerticalBarTransform: JSCodeShiftTransformer = (root) => {
root
.find(j.ObjectProperty, { key: { name: 'cellRendererParams' } })
.find(j.ObjectProperty, { key: { name: 'sparklineOptions' } })
Expand All @@ -14,3 +14,4 @@ export const columnToVerticalBarTransform: JSCodeShiftTransformer = (root) =>
path.replace(j.objectProperty(j.identifier('type'), j.stringLiteral('bar')));
path.insertAfter(j.objectProperty(j.identifier('direction'), j.stringLiteral(direction)));
});
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import j from 'jscodeshift';
import { JSCodeShiftTransformer } from '../../../plugins/jscodeshift';

export const removeCrosshairs: JSCodeShiftTransformer = (root) =>
export const removeCrosshairs: JSCodeShiftTransformer = (root) => {
root
.find(j.ObjectProperty, { key: { name: 'cellRendererParams' } })
.find(j.ObjectProperty, { key: { name: 'sparklineOptions' } })
.find(j.ObjectProperty, { key: { name: 'crosshairs' } })
.forEach((path) => path.replace());
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import j from 'jscodeshift';
import { JSCodeShiftTransformer } from '../../../plugins/jscodeshift';
import { newType, oldTypes } from './constants';

export const replaceTypes: JSCodeShiftTransformer = (root) =>
export const replaceTypes: JSCodeShiftTransformer = (root) => {
root
.find(j.TSTypeReference)
.filter((path) => oldTypes.includes((path.value.typeName as any).name))
.forEach((path) => path.replace(j.tsTypeReference(j.identifier(newType))));
};
16 changes: 12 additions & 4 deletions packages/codemod-utils/src/transform/js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ function transformJsFile<S>(
const transformContext: AstTransformContext<AstCliContext> = {
filename,
opts: {
warn(node: NodePath<AstNode> | null, message: string) {
warn(node, message) {
const error = createSourceCodeError(node, message);
uniqueErrors.set(error.message, { error, fatal: false });
},
fail(node: NodePath<AstNode> | null, message: string) {
fail(node, message) {
const error = createSourceCodeError(node, message);
uniqueErrors.set(error.message, { error, fatal: true });
},
Expand Down Expand Up @@ -99,6 +99,14 @@ function transformJsFile<S>(
};
}

function createSourceCodeError(node: NodePath<AstNode> | null, message: string): Error {
return node ? node.buildCodeFrameError(message) : new SyntaxError(message);
function createSourceCodeError(node: NodePath<AstNode> | Error | null, message: string): Error {
if (!node) {
return new SyntaxError(message);
}

if ('hub' in node) {
return node.buildCodeFrameError(message);
}

return node;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { describe, expect, onTestFinished, test } from 'vitest';
import { loadTransformScenarios } from '../../test/runners/transform';

import <%= identifier %> from '.';

const __dirname = dirname(fileURLToPath(import.meta.url));

describe(<%= identifier %>, () => {
const scenariosPath = join(__dirname, './__fixtures__/scenarios');
loadTransformScenarios(scenariosPath, {
transforms: [<%= identifier %>],
vitest: { describe, expect, test, onTestFinished },
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# jscodeshift Plugin

The `jscodeshift` plugin is a tool used for running codemods over JavaScript and TypeScript codebases. It leverages the `jscodeshift` library, which provides a simple API for transforming code using the power of abstract syntax trees (ASTs).
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createGrid } from '@ag-grid-community/core';

const gridApi = createGrid(document.body, {
columnDefs: [],
rowData: [],
});

gridApi.helloWorld();
gridApi?.goodbyeWorld();
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = [
new SyntaxError(`This method has been deprecated

> | gridApi.goodbyeWorld();
| ^^^^^^^^^^^^^^^^^^^^^^`),
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createGrid } from '@ag-grid-community/core';

const gridApi = createGrid(document.body, {
columnDefs: [],
rowData: [],
});

gridApi.sayHello("world");
gridApi?.goodbyeWorld();
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = [];
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"scenario": {
"input": "input.js",
"output": "output.js",
"errors": "output.errors.cjs",
"warnings": "output.warnings.cjs"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './transforms';
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { type TransformManifest } from '@ag-grid-devtools/types';

const manifest: TransformManifest = {
name: '<%= name %>',
description: '<%= description %>',
};

export default manifest;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "JSCodeshift",
"description": "Transform using JSCodeshift"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { JSCodeShiftTransformer } from '../../../plugins/jscodeshift';

// Transforms go here
export const myTransform: JSCodeShiftTransformer = (root) => {
// ...
};