Skip to content

Instantly share code, notes, and snippets.

@christianalfoni
Created January 27, 2021 09:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save christianalfoni/12e3beaa70e2fb4a1c5d55ca508707f7 to your computer and use it in GitHub Desktop.
Save christianalfoni/12e3beaa70e2fb4a1c5d55ca508707f7 to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
const cors = require('cors')
const chalk = require('chalk')
const figures = require('figures')
const express = require('express')
const bodyParser = require('body-parser')
const { resolve, relative } = require('path')
const jscodeshift = require('jscodeshift/dist/Runner')
const argv = require('yargs-parser')(process.argv.slice(2))
const resolveConfig = require('tailwindcss/resolveConfig')
const { Project, ScriptTarget, ts, Node } = require('ts-morph')
/*
private getAppSourceFile(classId: string) {
const fullPath =
classId === "index"
? path.resolve(APP_DIR, "index.ts")
: path.resolve(APP_DIR, classId, `index.ts`);
const sourceFile = this.project.getSourceFile(fullPath);
if (sourceFile) {
sourceFile.refreshFromFileSystemSync();
return sourceFile;
}
return this.project.addSourceFileAtPath(fullPath);
}
*/
const project = new Project({
compilerOptions: {
target: ScriptTarget.ES3
}
})
const PORT = 2406
const app = express()
app.use(cors({ maxAge: 600 }))
app.use(bodyParser.json())
const configPath = argv.c || argv.config
const verbose = argv.verbose || false
let config
if (configPath) config = resolveConfig(require(resolve(configPath)))
else config = resolveConfig({})
app.get('/config', async (req, res) => {
res.send(config)
})
app.post('/', async (req, res) => {
const { path, lineNumber, className } = req.body
if (!path) {
res.send('nothing')
return
}
let response = {}
try {
const sourceFile = project.addSourceFileAtPath(path)
const openingElement = sourceFile
.getDescendantsOfKind(ts.SyntaxKind.JsxOpeningElement)
.find(element => element.getStartLineNumber() === Number(lineNumber))
if (Node.isJsxOpeningElement(openingElement)) {
const classNameAttr =
openingElement.getAttribute('className') ||
openingElement.addAttribute('className')
const initializer = classNameAttr.getInitializer()
console.log('Opening element', String(initializer))
if (Node.isStringLiteral(initializer)) {
initializer.replaceWithText(`"${className}"`)
sourceFile.saveSync()
response.ok = true
} else {
response.error = true
}
} else {
response.ok = false
response.error = true
}
} catch (error) {
console.error(error)
response.error = true
}
/*
let transform = __dirname + '/transform.js'
// fire and forget
const response = await jscodeshift.run(transform, [path], {
lineNumber: parseInt(lineNumber, 10),
className,
silent: true,
runInBand: true,
verbose: verbose,
parser: 'tsx'
})
*/
const prettyPath = relative(process.cwd(), path) + ':' + lineNumber
if (response.ok) {
console.log(
chalk.green(figures.tick),
prettyPath,
'in',
response.timeElapsed + 's'
)
} else if (response.nochange) {
console.log(chalk.yellow(figures.line), 'did not change', prettyPath)
} else if (response.error) {
console.log(chalk.red(figures.cross), 'error changing', prettyPath)
}
res.send(response)
})
app.listen(PORT, () => console.log(`Listening for updates at ${PORT}`))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment