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
2 changes: 1 addition & 1 deletion biome.jsonc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.2.2/schema.json",
"$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
"files": {
"includes": ["."],
"experimentalScannerIgnores": ["codemods/**/tests/**/fixtures/**"]
Expand Down
33 changes: 33 additions & 0 deletions codemods/pos-api-smartgrid-to-action/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Dependencies
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Build artifacts
target/
dist/
build/

# Temporary files
*.tmp
*.temp
.cache/

# Environment files
.env
.env.local

# IDE files
.vscode/
.idea/
*.swp
*.swo

# OS files
.DS_Store
Thumbs.db

# Package bundles
*.tar.gz
*.tgz
39 changes: 39 additions & 0 deletions codemods/pos-api-smartgrid-to-action/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# testing

Transform legacy code patterns

## Installation

```bash
# Install from registry
codemod run testing

# Or run locally
codemod run -w workflow.yaml
```

## Usage

This codemod transforms typescript code by:

- Converting `var` declarations to `const`/`let`
- Removing debug statements
- Modernizing syntax patterns

## Development

```bash
# Test the transformation
npm test

# Validate the workflow
codemod validate -w workflow.yaml

# Publish to registry
codemod login
codemod publish
```

## License

MIT
18 changes: 18 additions & 0 deletions codemods/pos-api-smartgrid-to-action/codemod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
schema_version: "1.0"

name: "pos-api-smartgrid-to-action"
version: "0.1.0"
description: "Transform legacy code patterns"
author: "Shadi <[email protected]>"
license: "MIT"
workflow: "workflow.yaml"
category: "migration"

targets:
languages: ["typescript"]

keywords: ["transformation", "migration"]

registry:
access: "private"
visibility: "private"
14 changes: 14 additions & 0 deletions codemods/pos-api-smartgrid-to-action/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "testing",
"version": "0.1.0",
"description": "Transform legacy code patterns",
"type": "module",
"devDependencies": {
"@codemod.com/jssg-types": "^1.0.7",
"typescript": "^5.8.3"
},
"scripts": {
"test": "npx codemod@latest jssg test --language typescript ./scripts/codemod.ts",
"check-types": "npx tsc --noEmit"
}
}
81 changes: 81 additions & 0 deletions codemods/pos-api-smartgrid-to-action/scripts/codemod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { SgRoot, Edit, SgNode } from "codemod:ast-grep";
import type TS from "codemod:ast-grep/langs/typescript";
import {
isPOSUIExtensionsFile,
getApiAliases,
isValidObjectReference,
} from "../../../utils/ast-utils.js";

/**
* Transform api.smartGrid.presentModal() calls to api.action.presentModal()
* Handles various patterns including aliases, destructuring, optional chaining, etc.
* Only applies to files that import from POS UI Extensions packages.
*/
async function transform(root: SgRoot<TS>): Promise<string | null> {
const rootNode = root.root();

// Only transform files that import from POS UI Extensions (old or new packages)
if (!isPOSUIExtensionsFile(rootNode as unknown as SgNode)) {
return null;
}

const edits: Edit[] = [];

const apiAliases = getApiAliases(rootNode as unknown as SgNode);

const smartGridProps = rootNode
.findAll({
rule: {
kind: "property_identifier",
},
})
.filter((prop) => prop.text() === "smartGrid");

for (const prop of smartGridProps) {
if (!shouldTransformProperty(prop as unknown as SgNode, apiAliases)) {
continue;
}

edits.push(prop.replace("action"));
}

return edits.length === 0 ? null : rootNode.commitEdits(edits);
}

/**
* Determine if a smartGrid property should be transformed
* Only transforms api.smartGrid.presentModal() patterns
* @param prop - AST node
* @param apiAliases - Set of valid API aliases
*/
function shouldTransformProperty(
prop: SgNode,
apiAliases: Set<string>
): boolean {
// Get the parent member expression (e.g., "api.smartGrid")
const memberExpr = prop.parent();
if (!memberExpr || memberExpr.kind() !== "member_expression") return false;

// Check if the object is a valid API reference
const objectNode = memberExpr.field("object");
if (!objectNode) return false;

const objectText = objectNode.text();
if (!isValidObjectReference(objectText, apiAliases)) return false;

// Get the outer member expression (e.g., "api.smartGrid.presentModal")
const outerMemberExpr = memberExpr.parent();
if (!outerMemberExpr || outerMemberExpr.kind() !== "member_expression") {
return false;
}

// Only transform if the method is "presentModal"
const property = outerMemberExpr.field("property");
if (!property || property.text() !== "presentModal") return false;

// Only transform if this is a function call (not just property access)
const callExpr = outerMemberExpr.parent();
return callExpr ? callExpr.kind() === "call_expression" : false;
}

export default transform;
36 changes: 36 additions & 0 deletions codemods/pos-api-smartgrid-to-action/tests/fixtures/expected.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Basic case
api.action.presentModal();

// With arguments
api.action.presentModal(modalData, options);

// Assigned to variable
const result = api.action.presentModal();

// In method chain (promise)
const response = await api.action.presentModal().then(handleResponse);

// Alias receiver
const x = api;
x.action.presentModal({ title: "Hi" });

// Optional chaining
api?.action.presentModal();
const maybe = getApi()?.action.presentModal(cfg);

// Spacing and comments should be preserved
api /*A*/.action /*B*/
.presentModal /*C*/
(/*D*/);

// Already migrated (should be NO-OP)
api.action.presentModal(existing);

// Negative: different API object (should NOT transform)
someOtherApi.smartGrid.presentModal();

// Negative: different method (should NOT transform)
api.smartGrid.someOtherMethod();

// Negative: property access only (no call) — should NOT transform
const fn = api.smartGrid.presentModal;
36 changes: 36 additions & 0 deletions codemods/pos-api-smartgrid-to-action/tests/fixtures/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Basic case
api.smartGrid.presentModal();

// With arguments
api.smartGrid.presentModal(modalData, options);

// Assigned to variable
const result = api.smartGrid.presentModal();

// In method chain (promise)
const response = await api.smartGrid.presentModal().then(handleResponse);

// Alias receiver
const x = api;
x.smartGrid.presentModal({ title: "Hi" });

// Optional chaining
api?.smartGrid.presentModal();
const maybe = getApi()?.smartGrid.presentModal(cfg);

// Spacing and comments should be preserved
api /*A*/.smartGrid /*B*/
.presentModal /*C*/
(/*D*/);

// Already migrated (should be NO-OP)
api.action.presentModal(existing);

// Negative: different API object (should NOT transform)
someOtherApi.smartGrid.presentModal();

// Negative: different method (should NOT transform)
api.smartGrid.someOtherMethod();

// Negative: property access only (no call) — should NOT transform
const fn = api.smartGrid.presentModal;
17 changes: 17 additions & 0 deletions codemods/pos-api-smartgrid-to-action/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext",
"types": ["@codemod.com/jssg-types"],
"allowImportingTsExtensions": true,
"noEmit": true,
"verbatimModuleSyntax": true,
"erasableSyntaxOnly": true,
"strict": true,
"strictNullChecks": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true
},
"exclude": ["tests"]
}
11 changes: 11 additions & 0 deletions codemods/pos-api-smartgrid-to-action/workflow.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: "1"

nodes:
- id: apply-transforms
name: Apply AST Transformations
type: automatic
steps:
- name: "Scan typescript files and apply fixes"
js-ast-grep:
js_file: scripts/codemod.ts
language: "typescript"
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
"devDependencies": {
"husky": "^9.0.0",
"typescript": "^5.5.4"
},
"dependencies": {
"@codemod.com/jssg-types": "^1.0.9"
}
}

9 changes: 9 additions & 0 deletions pnpm-lock.yaml

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

Loading
Loading