Skip to content

Commit

Permalink
Parser Rework: NPM Package Support, import/export tracing, Internal S…
Browse files Browse the repository at this point in the history
…tructure Refactor, Playground and more (#66)

Parser Rework: NPM Package Support, import/export tracing, Internal Structure Refactor, Playground and more
  • Loading branch information
marcoroth authored Feb 25, 2024
2 parents 0a54a8f + e4da672 commit e0c2880
Show file tree
Hide file tree
Showing 158 changed files with 12,231 additions and 1,123 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/dist
node_modules/
coverage/
scratch/

yarn-error.log

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ const project = new Project("/Users/user/path/to/project")
const controllers = project.controllerDefinitions
const controller = controllers[0]

console.log(controller.methods)
console.log(controller.actionNames)
// => ["connect", "click", "disconnect"]

console.log(controller.targets)
console.log(controller.targetNames)
// => ["name", "output"]

console.log(controller.classes)
console.log(controller.classNames)
// => ["loading"]

console.log(controller.values)
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@
"dev": "yarn watch",
"clean": "rimraf dist",
"prerelease": "yarn build",
"install:fixtures": "node scripts/setupFixtures.mjs",
"postinstall": "yarn install:fixtures",
"pretest": "yarn install:fixtures",
"test": "vitest"
},
"dependencies": {
"@hotwired/stimulus-webpack-helpers": "^1.0.1",
"@typescript-eslint/typescript-estree": "^7.0.1",
"@typescript-eslint/visitor-keys": "^7.0.2",
"acorn-walk": "^8.3.1",
"astring": "^1.8.6",
"fs": "^0.0.1-security",
Expand All @@ -37,6 +41,6 @@
"ts-node": "^10.9.2",
"tslib": "^2.6.2",
"typescript": "^5.3.3",
"vitest": "^1.0.4"
"vitest": "^1.2.2"
}
}
24 changes: 24 additions & 0 deletions playground/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
34 changes: 34 additions & 0 deletions playground/app.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import express from "express"
import { Project, SourceFile, ClassDeclaration, ControllerDefinition, ExportDeclaration, ImportDeclaration } from "stimulus-parser"

const headers = { "Content-Type": "application/json" }

const app = express()
app.use(express.json())

function replacer(key, value) {
if (key === "project") return undefined
if (this instanceof SourceFile && key === "content") return undefined
if (this instanceof ImportDeclaration && key === "sourceFile") return undefined
if (this instanceof ExportDeclaration && key === "sourceFile") return undefined
if (this instanceof ClassDeclaration && key === "sourceFile") return undefined
if (this instanceof ControllerDefinition && key === "classDeclaration") return undefined

return value
}

app.post("/api/analyze", (request, response) => {
try {
const project = new Project("playground")
const sourceFile = new SourceFile(project, "playground_controller.js", request.body?.controller)

sourceFile.initialize()
sourceFile.analyze()

response.status(200).set(headers).end(JSON.stringify({ simple: sourceFile.inspect, full: sourceFile }, replacer))
} catch(e) {
response.status(500).set(headers).end(JSON.stringify({ error: e.message }))
}
});

export { app }
93 changes: 93 additions & 0 deletions playground/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Stimulus Parser Playground</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/js/all.min.js" integrity="sha512-GWzVrcGlo0TxTRvz9ttioyYJ+Wwk9Ck0G81D+eO63BaqHaJ3YZX9wuqjwgfcV/MrB2PhaVX9DkYVhbFpStnqpQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script defer data-domain="stimulus-parser.hotwire.io" src="https://plausible.io/js/script.js"></script>
</head>

<body class="bg-white flex flex-col" data-controller="playground">
<script type="module" src="/src/entry-client.ts"></script>

<div class="w-full">
<nav class="bg-white border px-8 flex h-16 justify-between">
<div class="flex ml-1 flex-1 items-stretch justify-start">
<div class="inline-flex items-center px-1 pt-1 text-lg font-medium text-gray-900">Stimulus Parser Playground</div>
</div>
</nav>

<div class="px-8 h-screen">
<div class="mx-2 grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="mt-6">
<div class="flex justify-between">
<div class="text-gray-900 rounded-md py-1.5 text-sm font-medium">Stimulus Controller</div>

<div class="flex gap-3">
<button data-action="click->playground#share" id="copy-share-url" class="text-gray-900 bg-gray-100 hover:bg-gray-200 rounded-md px-3 py-1.5 text-sm font-medium">
<i class="fas fa-copy"></i>
<i class="fas fa-circle-check text-green-600 hidden ease-in duration-300"></i>
<i class="fas fa-circle-xmark text-red-600 hidden ease-in duration-300"></i>

<span class="ml-1">Copy Share URL</span>
</button>

<button data-action="click->playground#insert click->playground#analyze" id="example" class="text-gray-900 bg-gray-100 hover:bg-gray-200 rounded-md px-3 py-1.5 text-sm font-medium">
<i class="fas fa-file w-4"></i>
<i class="fas fa-circle-check w-4 text-green-600 hidden ease-in duration-300"></i>

<span class="ml-1">Example</span>
</button>
</div>
</div>

<div class="mt-2">
<textarea data-playground-target="input" data-action="input->playground#analyze" id="input" class="p-3 bg-gray-50 font-mono w-full text-black rounded-md border border-gray-300 text-sm h-[30vh] md:h-[90vh]" placeholder="Paste Stimulus Controller here"></textarea>
</div>
</div>

<div class="mt-6" data-contoller="output">
<div class="flex justify-between">
<div class="text-gray-900 rounded-md px-0 py-1.5 text-sm font-medium">Parse Result</div>

<div class="flex gap-3">
<button data-playground-target="viewerButton" data-viewer="simple" data-action="click->playground#selectViewer" class="text-gray-900 bg-gray-100 hover:bg-gray-200 rounded-md px-3 py-1.5 text-sm font-medium data-[active=true]:bg-blue-600 data-[active=true]:hover:bg-blue-700 data-[active=true]:text-white" data-active="true">
<i class="fas fa-list"></i>
<span class="ml-1">Simple</span>
</button>

<button data-playground-target="viewerButton" data-viewer="full" data-action="click->playground#selectViewer" class="text-gray-900 bg-gray-100 hover:bg-gray-200 rounded-md px-3 py-1.5 text-sm font-medium data-[active=true]:bg-blue-600 data-[active=true]:hover:bg-blue-700 data-[active=true]:text-white" data-active="false">
<i class="fas fa-folder-tree"></i>
<span class="ml-1">Full</span>
</button>
</div>
</div>

<div class="mt-2">
<json-viewer data-playground-target="simpleViewer" class="py-0 px-5 rounded-lg font-mono h-[50vh] md:h-[90vh] overflow-scroll"></json-viewer>
<json-viewer data-playground-target="fullViewer" class="hidden py-0 px-5 rounded-lg font-mono h-[50vh] md:h-[90vh] overflow-scroll"></json-viewer>
</div>
</div>
</div>
</div>
</div>

<footer class="sticky bottom-0 bg-white">
<div class="w-full pt-3 pb-3 px-6 border-t border-gray-200">
<div class="flex flex-row justify-between items-center px-3 text-left">
<div class="flex justify-center text-sm text-black">
<span>Stimulus Parser Playground - Built by <a class="font-semibold" href="https://github.com/marcoroth" target="_blank">Marco Roth</a></span>
</div>
<div class="flex flex-col py-4 flex-row-reserve space-x-4 py-0">
<a href="https://github.com/marcoroth/stimulus-parser" target="_blank" class="opacity-50 hover:opacity-100">
<i class="h-6 w-6 fa-brands fa-github text-black"></i>
</a>
</div>
</div>
</div>
</footer>
</body>
</html>
26 changes: 26 additions & 0 deletions playground/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "stimulus-parser-playground",
"type": "module",
"scripts": {
"dev": "cross-env NODE_ENV=development node server.dev.mjs",
"build": "npm run build:client",
"build:client": "vite build --outDir dist/client",
"preview": "cross-env NODE_ENV=production node server.prod.mjs",
"serve": "cross-env NODE_ENV=production node server.prod.mjs"
},
"dependencies": {
"@alenaksu/json-viewer": "^2.0.1",
"@hotwired/stimulus": "^3.2.2",
"dedent": "^1.5.1",
"express": "^4.18.2",
"lz-string": "^1.5.0",
"stimulus-parser": "link:../"
},
"devDependencies": {
"@types/express": "^4.17.21",
"@types/node": "^20.10.5",
"cross-env": "^7.0.3",
"typescript": "^5.3.3",
"vite": "^5.0.10"
}
}
34 changes: 34 additions & 0 deletions playground/server.dev.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import fs from "fs"
import path from "path"

import { fileURLToPath } from "url"
import { createServer as createViteServer } from "vite"
import { app } from "./app.mjs"

const PORT = 5173
const __dirname = path.dirname(fileURLToPath(import.meta.url))

const vite = await createViteServer({
server: {
middlewareMode: {
server: app
}
},
appType: "custom"
})

app.use(vite.middlewares)

app.use("*", (request, response, next) => {
try {
const template = fs.readFileSync(path.resolve(__dirname, "index.html"), "utf-8")
response.status(200).set({ "Content-Type": "text/html" }).end(template)
} catch (e) {
vite.ssrFixStacktrace(e)
next(e)
}
})

app.listen(PORT, () => {
console.log(`Listing on http://localhost:${PORT}`)
})
18 changes: 18 additions & 0 deletions playground/server.prod.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import fs from "fs"
import path from "path"
import express from "express"

import { fileURLToPath } from "url"
import { app } from "./app.mjs"

app.use(express.static(path.resolve(path.dirname(fileURLToPath(import.meta.url)), "dist/client"), { index: false }))

const template = fs.readFileSync("./dist/client/index.html", "utf-8")

app.use("*", (request, response, next) => {
response.status(200).set({ "Content-Type": "text/html" }).end(template)
})

app.listen(5173, () => {
console.log("Listing on http://localhost:5173")
})
6 changes: 6 additions & 0 deletions playground/src/controllers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Application } from "@hotwired/stimulus"
import PlaygroundController from "./playground_controller"

const application = Application.start()

application.register("playground", PlaygroundController)
Loading

0 comments on commit e0c2880

Please sign in to comment.