diff --git a/.gitmodules b/.gitmodules
index 62d052e..c90ee3e 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -3,4 +3,4 @@
url = https://github.com/Engraph-dev/shared-schema
[submodule "src/util/defs"]
path = src/util/defs
- url = https://github.com/Engraph-dev/shared-typedefs
+ url = https://github.com/Engraph-dev/shared-typedefs
\ No newline at end of file
diff --git a/tests/typescript/1-basic-imports/index.ts b/eval-cases/typescript/1-basic-imports/index.ts
similarity index 100%
rename from tests/typescript/1-basic-imports/index.ts
rename to eval-cases/typescript/1-basic-imports/index.ts
diff --git a/tests/typescript/1-basic-imports/pkg/index.ts b/eval-cases/typescript/1-basic-imports/pkg/index.ts
similarity index 100%
rename from tests/typescript/1-basic-imports/pkg/index.ts
rename to eval-cases/typescript/1-basic-imports/pkg/index.ts
diff --git a/tests/typescript/1-basic-imports/tsconfig.json b/eval-cases/typescript/1-basic-imports/tsconfig.json
similarity index 100%
rename from tests/typescript/1-basic-imports/tsconfig.json
rename to eval-cases/typescript/1-basic-imports/tsconfig.json
diff --git a/tests/typescript/2-poisoned-source/index.ts b/eval-cases/typescript/2-poisoned-source/index.ts
similarity index 100%
rename from tests/typescript/2-poisoned-source/index.ts
rename to eval-cases/typescript/2-poisoned-source/index.ts
diff --git a/tests/typescript/2-poisoned-source/pkg/index.ts b/eval-cases/typescript/2-poisoned-source/pkg/index.ts
similarity index 100%
rename from tests/typescript/2-poisoned-source/pkg/index.ts
rename to eval-cases/typescript/2-poisoned-source/pkg/index.ts
diff --git a/tests/typescript/2-poisoned-source/tsconfig.json b/eval-cases/typescript/2-poisoned-source/tsconfig.json
similarity index 100%
rename from tests/typescript/2-poisoned-source/tsconfig.json
rename to eval-cases/typescript/2-poisoned-source/tsconfig.json
diff --git a/eval-cases/typescript/3-portfolio-website/src/assets/term.ico b/eval-cases/typescript/3-portfolio-website/src/assets/term.ico
new file mode 100755
index 0000000..27e09e3
Binary files /dev/null and b/eval-cases/typescript/3-portfolio-website/src/assets/term.ico differ
diff --git a/eval-cases/typescript/3-portfolio-website/src/assets/term.svg b/eval-cases/typescript/3-portfolio-website/src/assets/term.svg
new file mode 100755
index 0000000..03eabc2
--- /dev/null
+++ b/eval-cases/typescript/3-portfolio-website/src/assets/term.svg
@@ -0,0 +1,4 @@
+
diff --git a/eval-cases/typescript/3-portfolio-website/src/components/ShellOutput.tsx b/eval-cases/typescript/3-portfolio-website/src/components/ShellOutput.tsx
new file mode 100755
index 0000000..3c7fc50
--- /dev/null
+++ b/eval-cases/typescript/3-portfolio-website/src/components/ShellOutput.tsx
@@ -0,0 +1,38 @@
+import { isURL } from "@/utils/common"
+
+export type ShellOutputProps = {
+ textContent: string
+ overrideColor?: string
+}
+
+export function ShellOutput(props: ShellOutputProps) {
+ const { overrideColor = "termwhite", textContent } = props
+
+ const isContentURL = isURL(textContent)
+
+ const forceDeadText = (
+ <>
+
+
+
+
+
+ >
+ )
+
+ return (
+
+ {isContentURL ? (
+
+ {textContent}
+
+ ) : (
+ textContent
+ )}
+
+ )
+}
diff --git a/eval-cases/typescript/3-portfolio-website/src/components/ShellWindow.tsx b/eval-cases/typescript/3-portfolio-website/src/components/ShellWindow.tsx
new file mode 100755
index 0000000..18e0ddc
--- /dev/null
+++ b/eval-cases/typescript/3-portfolio-website/src/components/ShellWindow.tsx
@@ -0,0 +1,239 @@
+import { ShellOutput } from "@/components/ShellOutput"
+import { execCommand, parseCommandInput } from "@/utils/commandREPL"
+import { KONAMI_CODE, generateInitString } from "@/utils/common"
+import { useCommandHistory } from "@/utils/hooks/useCommandHistory"
+import { useSecretCode } from "@/utils/hooks/useSecretCode"
+import { ShellHandle } from "@/utils/typedef"
+import { useCallback, useEffect, useMemo, useRef, useState } from "react"
+
+export type ShellWindowProps = {}
+
+export function ShellWindow(props: ShellWindowProps) {
+ const [shellLocked, setShellLocked] = useState(false)
+
+ const commandHistory = useCommandHistory()
+
+ const [shellContent, setShellContent] = useState([
+ generateInitString(),
+ ])
+
+ const [inputText, setInputText] = useState("")
+
+ const [shellColor, setShellColor] = useState("termwhite")
+
+ const inputRef = useRef(null)
+ const termOutputRef = useRef(null)
+ const lastOutputRef = useRef(null)
+
+ const shellHandle: ShellHandle = useMemo(() => {
+ const memoHandle: ShellHandle = {
+ lockHandle: () => {
+ setShellLocked(true)
+ },
+ unlockHandle: () => {
+ setShellLocked(false)
+ },
+ writeLine: (outString) => {
+ setShellContent((prevContent) => {
+ return [...prevContent, outString]
+ })
+ },
+ clearShell: () => {
+ setShellContent([generateInitString()])
+ },
+ setShellColor: (newColor) => {
+ setShellColor(newColor)
+ },
+ }
+ return memoHandle
+ }, [setShellLocked, setShellContent])
+
+ const { onKeyPress } = useSecretCode({
+ codeSequence: KONAMI_CODE,
+ onUnlock: () => {
+ shellHandle.lockHandle()
+ shellHandle.writeLine(
+ "Buffer overflow! You've unlocked SUDO mode. This doesn't do much as of now!",
+ )
+ shellHandle.unlockHandle()
+ },
+ })
+
+ const executeUserInput = useCallback(() => {
+ const parsedCommand = parseCommandInput(inputText)
+ if (parsedCommand.commandName !== "NOOP") {
+ commandHistory.addCommand(parsedCommand)
+ }
+ setShellContent((prevContent) => {
+ return [...prevContent, `> ${inputText}`]
+ })
+ if (parsedCommand.commandName !== "NOOP") {
+ execCommand(parsedCommand, shellHandle)
+ }
+ setInputText("")
+ }, [commandHistory, inputText, shellHandle])
+
+ useEffect(() => {
+ const textRef = inputRef.current
+ if (!textRef) {
+ return
+ }
+
+ const eventHandler = (eventData: KeyboardEvent) => {
+ if (shellLocked) {
+ // Some command is writing
+ return
+ }
+ if (eventData.isComposing) {
+ return
+ }
+
+ const keyData = eventData.key
+
+ onKeyPress(keyData)
+
+ if (keyData.startsWith("Arrow")) {
+ if (keyData === "ArrowLeft" || keyData === "ArrowRight") {
+ // Do nothing
+ } else if (keyData === "ArrowUp") {
+ const partialCommand = parseCommandInput(inputText)
+ const prevCommand = commandHistory.rewindCommand()
+ setInputText(prevCommand.rawCommand)
+ } else {
+ const nextCommand = commandHistory.forwardCommand()
+ setInputText(nextCommand.rawCommand)
+ }
+ return
+ }
+
+ if (keyData === "Enter") {
+ executeUserInput()
+ return
+ }
+ }
+
+ textRef.addEventListener("keydown", eventHandler)
+
+ return () => {
+ if (!textRef) {
+ return
+ }
+ textRef.removeEventListener("keydown", eventHandler)
+ }
+ }, [
+ commandHistory,
+ executeUserInput,
+ inputText,
+ onKeyPress,
+ shellHandle,
+ shellLocked,
+ ])
+
+ useEffect(() => {
+ if (lastOutputRef.current && termOutputRef.current) {
+ termOutputRef.current.scrollTop = lastOutputRef.current.offsetTop
+ }
+ })
+
+ // If you're seeing ugly scrollbars blame Chrome / Chromium / Edge or whatever fork you are running.
+ // Works perfectly fucking fine in firefox
+
+ return (
+
+
+
+
+ {`ArnitDOS ${shellLocked ? ":O" : ":)"}`}
+
+
+ {/* @ts-ignore */}
+
+ {shellContent.map((contentString, contentIdx) => {
+ return (
+ // @ts-ignore
+
+
+
+ )
+ })}
+
+
+
+
+ {shellLocked ? "Locked" : "Input"}
+
+ {">"}
+
+
{
+ setInputText(ev.target.value)
+ }}
+ value={inputText}
+ />
+
+ {"<"}
+
+
+
+
+
+
+
+ )
+}
diff --git a/eval-cases/typescript/3-portfolio-website/src/pages/_app.tsx b/eval-cases/typescript/3-portfolio-website/src/pages/_app.tsx
new file mode 100755
index 0000000..b650264
--- /dev/null
+++ b/eval-cases/typescript/3-portfolio-website/src/pages/_app.tsx
@@ -0,0 +1,6 @@
+import "@/styles/globals.css"
+import type { AppProps } from "next/app"
+
+export default function App({ Component, pageProps }: AppProps) {
+ return
+}
diff --git a/eval-cases/typescript/3-portfolio-website/src/pages/_document.tsx b/eval-cases/typescript/3-portfolio-website/src/pages/_document.tsx
new file mode 100755
index 0000000..8409217
--- /dev/null
+++ b/eval-cases/typescript/3-portfolio-website/src/pages/_document.tsx
@@ -0,0 +1,13 @@
+import { Head, Html, Main, NextScript } from "next/document"
+
+export default function Document() {
+ return (
+
+
+
+
+
+
+
+ )
+}
diff --git a/eval-cases/typescript/3-portfolio-website/src/pages/index.tsx b/eval-cases/typescript/3-portfolio-website/src/pages/index.tsx
new file mode 100755
index 0000000..2ec1381
--- /dev/null
+++ b/eval-cases/typescript/3-portfolio-website/src/pages/index.tsx
@@ -0,0 +1,26 @@
+import { ShellWindow } from "@/components/ShellWindow"
+import { getVersionString } from "@/utils/common"
+import Head from "next/head"
+
+export default function IndexPage() {
+ return (
+ <>
+
+ {`ArnitDOS ${getVersionString()}`}
+
+
+
+
+
+ >
+ )
+}
diff --git a/eval-cases/typescript/3-portfolio-website/src/styles/globals.css b/eval-cases/typescript/3-portfolio-website/src/styles/globals.css
new file mode 100755
index 0000000..0b99492
--- /dev/null
+++ b/eval-cases/typescript/3-portfolio-website/src/styles/globals.css
@@ -0,0 +1,35 @@
+@import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono&display=swap");
+
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@keyframes blink-anim {
+ 0% {
+ opacity: 0;
+ }
+ 49% {
+ opacity: 0;
+ }
+ 50% {
+ opacity: 1;
+ }
+ 99% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0;
+ }
+}
+
+.blink {
+ animation: blink-anim 1s infinite;
+}
+
+.scrollbar-hidden {
+ scrollbar-width: none;
+}
+
+::-webkit-scrollbar {
+ display: none;
+}
diff --git a/eval-cases/typescript/3-portfolio-website/src/utils/commandREPL.ts b/eval-cases/typescript/3-portfolio-website/src/utils/commandREPL.ts
new file mode 100755
index 0000000..56b0d90
--- /dev/null
+++ b/eval-cases/typescript/3-portfolio-website/src/utils/commandREPL.ts
@@ -0,0 +1,95 @@
+import { EXECUTABLE_COMMANDS, isValidExecCommand } from "@/utils/commands"
+import { COMMAND_SPLIT_REGEXP } from "@/utils/globals"
+import {
+ Command,
+ CommandOption,
+ CommandOptionType,
+ ShellHandle,
+} from "@/utils/typedef"
+
+/**
+ * @summary Generates a Command structure from a given input string
+ * **/
+export function parseCommandInput(commandString: string): Command {
+ let inputString = commandString.trim()
+ inputString = inputString.toLowerCase()
+
+ if (inputString.length === 0) {
+ // Empty command
+ return {
+ commandName: "NOOP",
+ rawCommand: "",
+ commandArgs: [],
+ commandOptions: [],
+ }
+ }
+
+ const stringTokens = inputString.split(COMMAND_SPLIT_REGEXP)
+ const cleanTokens = stringTokens.filter((stringToken) => {
+ return (
+ stringToken.length > 0 || // Empty string
+ stringToken == "-" ||
+ stringToken == "--" // Only long/short opt flag passed, we need more data after -
+ )
+ })
+ const firstKeyword = cleanTokens[0]
+
+ const inputArgs = cleanTokens.slice(1)
+
+ const argList = inputArgs.filter((argString) => {
+ return !argString.startsWith("-")
+ })
+
+ const rawOptList = inputArgs.filter((optString) => {
+ return optString.startsWith("-")
+ })
+
+ const mappedOptList = rawOptList.map((optString): CommandOption => {
+ if (optString.startsWith("--")) {
+ const trimmedOptString = optString.slice(2)
+ return {
+ optType: CommandOptionType.LONG_OPT,
+ optionValue: trimmedOptString,
+ }
+ } else {
+ const trimmedOptString = optString.slice(1)
+ return {
+ optType: CommandOptionType.SHORT_OPT,
+ optionValue: trimmedOptString[0],
+ }
+ }
+ })
+
+ return {
+ commandName: firstKeyword.toUpperCase(),
+ rawCommand: commandString.trim(),
+ commandArgs: argList,
+ commandOptions: mappedOptList,
+ }
+}
+
+export function execCommand(targetCommand: Command, shellHandle: ShellHandle) {
+ const isValidCommand = isValidExecCommand(targetCommand.commandName)
+ if (!isValidCommand) {
+ shellHandle.lockHandle()
+ shellHandle.writeLine(
+ `${targetCommand.rawCommand}: Not a valid command!`,
+ )
+ shellHandle.unlockHandle()
+ } else {
+ const matchingCommand = EXECUTABLE_COMMANDS.find((execCommand) => {
+ return execCommand.commandExecutable === targetCommand.commandName
+ })
+ if (matchingCommand === undefined) {
+ shellHandle.lockHandle()
+ shellHandle.writeLine(`${targetCommand.rawCommand}: Error!`)
+ shellHandle.unlockHandle()
+ } else {
+ matchingCommand.executeCommand(
+ targetCommand.commandArgs,
+ targetCommand.commandOptions,
+ shellHandle,
+ )
+ }
+ }
+}
diff --git a/eval-cases/typescript/3-portfolio-website/src/utils/commands.ts b/eval-cases/typescript/3-portfolio-website/src/utils/commands.ts
new file mode 100755
index 0000000..bd86964
--- /dev/null
+++ b/eval-cases/typescript/3-portfolio-website/src/utils/commands.ts
@@ -0,0 +1,239 @@
+import {
+ LIST_DATA,
+ PROJECT_DATA,
+ RESUME_LINK,
+ getVersionString,
+} from "@/utils/common"
+import { ExecutableCommand } from "@/utils/typedef"
+
+const HELP_STRING_MAP: Record = {
+ HELP: "Great, now we're stuck in a loop! Try a different command, maybe that will break it...",
+ HELLO: "Do you need an introduction? Say `Hello!`",
+ LIST: "Enumerate some stuff - such as `projects`, `experience`, `hobbies` or `academics`",
+ CONTACT: "Want to get in touch with me?, say `contact` and find out how!",
+ RESUME: "Now we're talking! Punch in `resume` to get a quick link to my latest Resume",
+ PROJECT:
+ "Want to dig deeper into my works? Hit `project `, you'll find more information there!",
+ SOCIAL: "There's more to me than bits and bytes! Give me a ping on any of my `social` links!",
+ CLEAR: "Two well-dressed men in black pull out a very suspicious device that emits a bright flash...",
+ COLOR: "Bring out the colors! Usage: `color `. Accepts `red|green|yellow|blue|pink`. Run without arguments to reset",
+ SLEEP: "*Yawn* I've been up too long! Put me to sleep with `sleep `",
+}
+
+export const EXECUTABLE_COMMANDS: ExecutableCommand[] = [
+ {
+ commandExecutable: "NOOP",
+ executeCommand: (commandArgs, commandOpts, shellHandle) => {
+ void 0
+ // Do nothing, this is a noop command!
+ },
+ },
+ {
+ commandExecutable: "CLEAR",
+ executeCommand: (commandArgs, commandOpts, shellHandle) => {
+ shellHandle.lockHandle()
+ shellHandle.clearShell()
+ shellHandle.unlockHandle()
+ },
+ },
+ {
+ commandExecutable: "HELLO",
+ executeCommand: (commandArgs, commandOpts, shellHandle) => {
+ shellHandle.lockHandle()
+ shellHandle.writeLine(
+ "Hey there! Welcome to ArnitDOS, I'm an interactive shell, here to guide you through Arnav's Portfolio!\nType `help` to list all available commands.",
+ )
+ shellHandle.unlockHandle()
+ },
+ },
+ {
+ commandExecutable: "HELP",
+ executeCommand: (commandArgs, commandOpts, shellHandle) => {
+ const verString = getVersionString()
+ shellHandle.lockHandle()
+ if (commandArgs.length === 0) {
+ shellHandle.writeLine(
+ "Need help? Got you covered - try running one of the following commands, or `help ` for more information",
+ )
+ VALID_COMMAND_NAMES.forEach((commandKey, commandIdx) => {
+ shellHandle.writeLine(
+ `${commandIdx + 1}) ${commandKey.toLowerCase()}`,
+ )
+ })
+ } else {
+ for (let commandArg of commandArgs) {
+ commandArg = commandArg.toUpperCase()
+ if (VALID_COMMAND_NAMES.includes(commandArg)) {
+ const helpText = HELP_STRING_MAP[commandArg]
+ shellHandle.writeLine(
+ `${commandArg.toLowerCase()}: ${helpText}`,
+ )
+ } else {
+ shellHandle.writeLine(
+ "Sorry, can't really help with that :(",
+ )
+ }
+ }
+ }
+ shellHandle.unlockHandle()
+ },
+ },
+ {
+ commandExecutable: "LIST",
+ executeCommand: (commandArgs, commandOpts, shellHandle) => {
+ shellHandle.lockHandle()
+ if (commandArgs.length === 0) {
+ shellHandle.writeLine(
+ "Tell me something to list! Like `list projects|academics|experience|hobbies`",
+ )
+ } else if (commandArgs.length === 1) {
+ const firstArg = commandArgs[0]
+ const uppercaseArg = firstArg.toUpperCase()
+ if (Object.keys(LIST_DATA).includes(uppercaseArg)) {
+ const listPoints = LIST_DATA[uppercaseArg]
+ for (const listPoint of listPoints) {
+ shellHandle.writeLine(listPoint)
+ }
+ } else {
+ shellHandle.writeLine(
+ "I can't list that, try something relevant!",
+ )
+ }
+ } else {
+ shellHandle.writeLine(
+ "Too many things to list! Try one at a time!",
+ )
+ }
+ shellHandle.unlockHandle()
+ },
+ },
+ {
+ commandExecutable: "CONTACT",
+ executeCommand: (commandArgs, commandOpts, shellHandle) => {
+ shellHandle.lockHandle()
+ shellHandle.writeLine(
+ "Shoot me a mail at the address below, and I'll get in touch with you",
+ )
+ shellHandle.writeLine("mailto:hello@arnitdo.dev")
+ shellHandle.unlockHandle()
+ },
+ },
+ {
+ commandExecutable: "RESUME",
+ executeCommand: (commandArgs, commandOpts, shellHandle) => {
+ shellHandle.lockHandle()
+ shellHandle.writeLine("View my resume at the link below!")
+ shellHandle.writeLine("")
+ shellHandle.writeLine(RESUME_LINK)
+ shellHandle.writeLine("")
+ shellHandle.unlockHandle()
+ },
+ },
+ {
+ commandExecutable: "PROJECT",
+ executeCommand: (commandArgs, commandOpts, shellHandle) => {
+ shellHandle.lockHandle()
+ if (commandArgs.length === 0) {
+ shellHandle.writeLine(
+ "Give me a project id, I'll tell you more! Use the `list` command",
+ )
+ } else if (commandArgs.length === 1) {
+ const projectId = commandArgs[0].toUpperCase()
+ if (Object.keys(PROJECT_DATA).includes(projectId)) {
+ const projectData = PROJECT_DATA[projectId]
+ const {
+ projectTitle,
+ projectDescription,
+ githubLink,
+ projectDuration,
+ projectNote,
+ } = projectData
+ shellHandle.writeLine(`Title: ${projectTitle}`)
+ shellHandle.writeLine(`Description: ${projectDescription}`)
+ shellHandle.writeLine("GitHub Link")
+ shellHandle.writeLine(githubLink)
+ if (projectDuration) {
+ shellHandle.writeLine(
+ `Developed from: ${projectDuration}`,
+ )
+ } else {
+ shellHandle.writeLine(`Still under development`)
+ }
+ if (projectNote) {
+ shellHandle.writeLine(`Note: ${projectNote}`)
+ }
+ } else {
+ shellHandle.writeLine("That's not a valid project ID!")
+ }
+ } else {
+ shellHandle.writeLine(
+ "That's way too many projects! Try one at a time.",
+ )
+ }
+ shellHandle.unlockHandle()
+ },
+ },
+ {
+ commandExecutable: "SOCIAL",
+ executeCommand: (commandArgs, commandOpts, shellHandle) => {
+ shellHandle.lockHandle()
+ shellHandle.writeLine(
+ "Reach out to me on any of the below links, and I'll get in touch!",
+ )
+ shellHandle.writeLine("GitHub @arnitdo")
+ shellHandle.writeLine("https://github.com/arnitdo")
+ shellHandle.writeLine("Instagram: @arnitdo")
+ shellHandle.writeLine("https://instagram.com/arnitdo")
+ shellHandle.writeLine("LinkedIn: @arnitdo")
+ shellHandle.writeLine("https://linkedin.com/in/arnitdo")
+ shellHandle.unlockHandle()
+ },
+ },
+ {
+ commandExecutable: "COLOR",
+ executeCommand: (commandArgs, commandOpts, shellHandle) => {
+ if (commandArgs.length === 0) {
+ shellHandle.setShellColor("termwhite")
+ } else {
+ const colorArg = commandArgs[0]
+ shellHandle.setShellColor(colorArg)
+ }
+ },
+ },
+ {
+ commandExecutable: "SLEEP",
+ executeCommand: (commandArgs, commandOpts, shellHandle) => {
+ shellHandle.lockHandle()
+ if (commandArgs.length === 0) {
+ shellHandle.writeLine(
+ "I can't just go to sleep forever, you know?",
+ )
+ shellHandle.unlockHandle()
+ } else {
+ const firstArg = commandArgs[0]
+ const numericArg = Number.parseInt(firstArg)
+ if (Number.isNaN(numericArg) || numericArg < 1) {
+ shellHandle.writeLine("That's not a valid input!")
+ shellHandle.unlockHandle()
+ } else {
+ setTimeout(
+ shellHandle.unlockHandle,
+ numericArg * 1000, // ms
+ )
+ }
+ }
+ },
+ },
+]
+
+const FORBIDDEN_COMMANDS = ["NOOP"]
+
+const VALID_COMMAND_NAMES = EXECUTABLE_COMMANDS.map((commandStruct) => {
+ return commandStruct.commandExecutable
+}).filter((commandName) => {
+ return !FORBIDDEN_COMMANDS.includes(commandName)
+})
+
+export function isValidExecCommand(commandName: string) {
+ return VALID_COMMAND_NAMES.includes(commandName)
+}
diff --git a/eval-cases/typescript/3-portfolio-website/src/utils/common.ts b/eval-cases/typescript/3-portfolio-website/src/utils/common.ts
new file mode 100755
index 0000000..b33d580
--- /dev/null
+++ b/eval-cases/typescript/3-portfolio-website/src/utils/common.ts
@@ -0,0 +1,168 @@
+export function getVersionString(): string {
+ const nowDate = new Date()
+ const nowYear = nowDate.getFullYear()
+ const nowMonth = nowDate.getMonth() + 1
+ const nowDayDate = nowDate.getDate()
+
+ return `v${nowYear}.${nowMonth}.${nowDayDate}`
+}
+
+export function generateInitString(): string {
+ return (
+ "ArnitDOS" + getVersionString() + ". Type `help` for more information."
+ )
+}
+
+export const RESUME_LINK =
+ "https://drive.google.com/file/d/1LjvdoobpPFOk9vGUV5reF9N_pN5UfO5i/view" as const
+
+export const LIST_DATA = {
+ EXPERIENCE: [
+ "I have worked as a Backend Developer Intern at Engaze.in from June 2024 to August 2024",
+ "I've also worked as a Freelance Web Developer for Pixels and Grids, developing websites and web applications",
+ "I've worked as a MERN Stack Developer Intern at CTO-Ninja from June 2023 to October 2023",
+ "I was also a part of GDSC DJSCE's Web Development Co-Committee for the academic year 2023-2024",
+ "I'm currently at the forefront of GDG DJSCE, as the Co-Lead for the academic year 2024-2025",
+ ],
+ PROJECTS: [
+ "I've worked on various projects in Typescript, Javascript, Postgres, Python, C++ and the MERN/PERN Stack. Here are some of my personal favorites.",
+ "To learn more about each project, use the `project ` command, and use one of the names in the [square brackets] below",
+ "[mimicai] A customisable AI mimc for having custom conversations",
+ "[thinq] ThinQ a full stack online education platform using NextJS and PostgreSQL",
+ "[blitzai] BlitzAI is a cutting-edge SaaS platform designed to empower content creators by integrating AI seamlessly into their video creation workflows",
+ "[nutrino] Nutrino is a web application designed to help individuals with allergies and dietary restrictions navigate the world of food effortlessly",
+ "[versura] Versura is a revolutionary blockchain based crowdfunding platform, developed as an academic project at SVKM's SBMP",
+ "[axess] Axess is a prize-winning QR-Code based access control system integrating fine-tuned permissions and user management",
+ "[gpiostudio] GPIOStudio is a GUI for developing Python scripts for the Raspberry Pi GPIO, built using Qt5 and C++11",
+ "[drone] I've worked on developing software for integrating voice control with PixHawk drones using Raspberry Pis",
+ ],
+ HOBBIES: [
+ "I love astronomy, stargazing, working out, and last but not the least, tinkering! You'll always find a spare screwdriver or patch cord in my bag ;)",
+ ],
+ ACADEMICS: [
+ "Here are some of my academic achievements -",
+ "I'm currently pursuing a B.Tech Degree in Computer Engineering at SVKM's DJSCE",
+ "I hold a Diploma in Computer Engineering from SVKM's Shri Bhagubhai Mafatlal Polytechnic",
+ "I've participated in various technical competitions and hackathons, mosty notably winning the 2nd Prize at KJSCE Devopia Hackathon",
+ "I have also had the honor of being part of the organising committee as the Technical Head for PolyHacks 1.0 Hackathon at SVKM's SBMP",
+ ],
+} as Record
+
+type ProjectInfo = {
+ projectTitle: string
+ projectDescription: string
+ githubLink: string
+ projectNote?: string
+ projectDuration?: string
+}
+
+export const PROJECT_DATA: Record = {
+ MIMICAI: {
+ projectTitle: "MimicAI - A customisable AI mimic for conversations",
+ projectDescription:
+ "MimicAI is a customisable AI mimic for users to have conversations with. " +
+ "It allows users to fork conversations from a message, trying out different messages and responses",
+ githubLink: "https://mimicai.arnitdo.dev",
+ projectDuration: "12/2024 - 12/2024",
+ projectNote: "Developed in under 24 hours",
+ },
+ THINQ: {
+ projectTitle: "ThinQ - A virtual classroom enhancement platform",
+ projectDescription:
+ "ThinQ is a comprehensive solution for virtual classrooms, providing a wide range of features to enhance the online learning experience." +
+ "It features calendar integrations, video calling, attention detection among a wide variety of features designed to improve online classroom teaching",
+ projectNote: "This project was developed at PICT TechFiesta 2024",
+ githubLink: "https://github.com/arnitdo/ThinQ",
+ projectDuration: "02/2024 - 04/2023",
+ },
+ BLITZAI: {
+ projectTitle: "BlitzAI: Next-Gen AI Video Creation SaaS",
+ projectDescription:
+ "BlitzAI is a cutting-edge SaaS platform designed to empower content creators by integrating AI seamlessly into their video creation workflows." +
+ "With a user-friendly UI and a modular approach, BlitzAI allows users to pick and choose AI-driven features at any step of the content creation process.",
+ projectNote: "This project was developed at Datathon 3.0 at KJSCE",
+ githubLink: "https://github.com/arnitdo/Blitz.AI-Datathon-3",
+ projectDuration: "02/2024",
+ },
+ NUTRINO: {
+ projectTitle: "Nutrino: Your Own Food Assistant",
+ projectDescription:
+ "Nutrino is a web application designed to help individuals with allergies and dietary restrictions navigate the world of food effortlessly. " +
+ "By utilizing advanced machine learning models, Nutrino provides users with powerful tools to detect ingredients, " +
+ "suggest alternatives, and offer a delightful cooking experience.",
+ projectNote: "This project was developed at TSEC Hack24",
+ githubLink: "https://github.com/arnitdo/Nutrino",
+ projectDuration: "01/2024 - 02/2024",
+ },
+ VERSURA: {
+ projectTitle:
+ "Versura - A revolutionary blockchain based crowdfunding platform",
+ projectDescription:
+ "Versura is a web+blockchain based crowdfunding platform developed as part of " +
+ "academic curriculum. Integrated AWS RDS for database provisioning and storage. " +
+ "Implemented project front-end using NextJS and Elastic UI. Blockchain" +
+ "functionality implemented using Metamask and Web3.js",
+ projectNote:
+ "This project was developed as part of an academic project requirement for completing my Diploma in Computer Engineering",
+ githubLink: "https://github.com/arnitdo/versura",
+ projectDuration: "02/2023 - 06/2023",
+ },
+ AXESS: {
+ projectTitle: "Axess - A innovative access control system",
+ projectDescription:
+ "Axess is an innovative QR-Code based access control management system developed at VESP's " +
+ "Technothon 2023. It integrates a fine-tuned permission system with a scalable QR-based location and entry/exit " +
+ "point-of-transit systems. Such functionality was achieved using NextUI, Google Cloud Firebase Firestore, and NextJS",
+ githubLink: "https://github.com/arnitdo/Axess",
+ projectNote:
+ "This project won the Third Prize at VESP's Technothon 2023",
+ projectDuration: "04/2023",
+ },
+ GPIOSTUDIO: {
+ projectTitle: "GPIO Studio",
+ projectDescription:
+ "Created a GPIO-Interfacing script generator GUI for Raspberry Pis and other IoT " +
+ "devices. Developed and utilized skills acquired in C++11 and Qt5 GUI Framework. " +
+ "Integrated various open source third-party libraries to provide data parsing and " +
+ "storage.",
+ githubLink: "https://github.com/arnitdo/GPIOStudio",
+ projectDuration: "08/2021 - 01/2022",
+ },
+ DRONE: {
+ projectTitle: "Voice Controlled Drone",
+ projectDescription:
+ "Developed a Voice Controlled Drone, implementing various protocols to enable " +
+ "communication between a PixHawk Flight Controller and Raspberry Pi SBC. Uses " +
+ "Google Cloud-based speech to text processing to analyze voice commands",
+ projectDuration: "01/2023 - 06/2023",
+ githubLink: "https://github.com/arnitdo/Voice-Controlled-Drone",
+ projectNote:
+ "This was a collaborative effort as part of an academic project",
+ },
+} as const
+
+export function isURL(urlLikeString: string) {
+ try {
+ const actualURL = new URL(urlLikeString)
+ return (
+ actualURL.protocol.startsWith("http") ||
+ actualURL.protocol.startsWith("mailto")
+ )
+ } catch {
+ return false
+ }
+}
+
+// ^^vv<><>ba
+export const KONAMI_CODE = [
+ "ArrowUp",
+ "ArrowUp",
+ "ArrowDown",
+ "ArrowDown",
+ "ArrowLeft",
+ "ArrowRight",
+ "ArrowLeft",
+ "ArrowRight",
+ "b",
+ "a",
+]
diff --git a/eval-cases/typescript/3-portfolio-website/src/utils/globals.ts b/eval-cases/typescript/3-portfolio-website/src/utils/globals.ts
new file mode 100755
index 0000000..26ab384
--- /dev/null
+++ b/eval-cases/typescript/3-portfolio-website/src/utils/globals.ts
@@ -0,0 +1,3 @@
+export const COMMAND_SPLIT_REGEXP = /\s|\./gi
+
+export const EXIT_TIMEOUT = 5
diff --git a/tests/typescript/3-complex-implementation/index.ts b/eval-cases/typescript/3-portfolio-website/src/utils/hooks/useCommandHistory.ts
old mode 100644
new mode 100755
similarity index 97%
rename from tests/typescript/3-complex-implementation/index.ts
rename to eval-cases/typescript/3-portfolio-website/src/utils/hooks/useCommandHistory.ts
index 8d914dc..83b094b
--- a/tests/typescript/3-complex-implementation/index.ts
+++ b/eval-cases/typescript/3-portfolio-website/src/utils/hooks/useCommandHistory.ts
@@ -1,4 +1,4 @@
-import { Command } from "./typedef"
+import { Command } from "@/utils/typedef"
import { useCallback, useState } from "react"
type UseCommandHistoryOptions = {}
diff --git a/eval-cases/typescript/3-portfolio-website/src/utils/hooks/useSecretCode.ts b/eval-cases/typescript/3-portfolio-website/src/utils/hooks/useSecretCode.ts
new file mode 100755
index 0000000..4a8c476
--- /dev/null
+++ b/eval-cases/typescript/3-portfolio-website/src/utils/hooks/useSecretCode.ts
@@ -0,0 +1,47 @@
+import { useCallback, useState } from "react"
+
+export type UseSecretCodeArgs = {
+ onUnlock: () => void
+ codeSequence: string[]
+}
+
+export type SecretCodeRet = {
+ onKeyPress: (keyCode: string) => void
+}
+
+export function useSecretCode(args: UseSecretCodeArgs): SecretCodeRet {
+ const { onUnlock, codeSequence } = args
+ const [keyQueue, setKeyQueue] = useState([])
+
+ const onKeyPress = useCallback(
+ (keyCode: string) => {
+ let mergedQueue: string[] = []
+ if (keyQueue.length >= codeSequence.length) {
+ const copyQueue = [...keyQueue]
+ const slicedQueue = copyQueue.slice(1)
+ mergedQueue = [...slicedQueue, keyCode]
+ } else {
+ mergedQueue = [...keyQueue, keyCode]
+ }
+ if (mergedQueue.length === codeSequence.length) {
+ let matchFlag = true
+ for (let idx = 0; idx < codeSequence.length; idx++) {
+ if (mergedQueue[idx] !== codeSequence[idx]) {
+ matchFlag = false
+ }
+ }
+ if (matchFlag) {
+ onUnlock()
+ }
+ } else {
+ // Do nothing, code cannot be input
+ }
+ setKeyQueue(mergedQueue)
+ },
+ [codeSequence, keyQueue, onUnlock],
+ )
+
+ return {
+ onKeyPress: onKeyPress,
+ }
+}
diff --git a/tests/typescript/3-complex-implementation/typedef.ts b/eval-cases/typescript/3-portfolio-website/src/utils/typedef.ts
old mode 100644
new mode 100755
similarity index 100%
rename from tests/typescript/3-complex-implementation/typedef.ts
rename to eval-cases/typescript/3-portfolio-website/src/utils/typedef.ts
diff --git a/eval-cases/typescript/3-portfolio-website/tsconfig.json b/eval-cases/typescript/3-portfolio-website/tsconfig.json
new file mode 100755
index 0000000..80b02d8
--- /dev/null
+++ b/eval-cases/typescript/3-portfolio-website/tsconfig.json
@@ -0,0 +1,22 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true,
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"]
+}
diff --git a/package-lock.json b/package-lock.json
index ba1c7a7..9a48908 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,17 +1,20 @@
{
- "name": "project-parser",
+ "name": "engraph-worker",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "project-parser",
+ "name": "engraph-worker",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"@aws-sdk/client-sqs": "^3.726.1",
"@prisma/client": "^6.2.1",
+ "@types/express": "^5.0.0",
+ "cors": "^2.8.5",
"dotenv": "^16.4.5",
+ "express": "^4.21.2",
"neo4j-driver": "^5.27.0",
"octokit": "^4.1.0",
"openai": "^4.73.1",
@@ -26,6 +29,7 @@
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
+ "@types/cors": "^2.8.17",
"@types/node": "^22.10.1",
"husky": "^9.1.6",
"lint-staged": "^15.2.10",
@@ -2199,6 +2203,71 @@
"integrity": "sha512-nD0Z9fNIZcxYX5Mai2CTmFD7wX7UldCkW2ezCF8D1T5hdiLsnTWDGRpfRYntU6VjTdLQjOvyszru7I1c1oCQew==",
"license": "MIT"
},
+ "node_modules/@types/body-parser": {
+ "version": "1.19.5",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
+ "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.38",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
+ "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/cors": {
+ "version": "2.8.17",
+ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
+ "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/express": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz",
+ "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^5.0.0",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "node_modules/@types/express-serve-static-core": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz",
+ "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/@types/http-errors": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
+ "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/mime": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
+ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+ "license": "MIT"
+ },
"node_modules/@types/node": {
"version": "22.10.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz",
@@ -2218,6 +2287,39 @@
"form-data": "^4.0.0"
}
},
+ "node_modules/@types/qs": {
+ "version": "6.9.18",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz",
+ "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/range-parser": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
+ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+ "license": "MIT"
+ },
+ "node_modules/@types/send": {
+ "version": "0.17.4",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
+ "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mime": "^1",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/serve-static": {
+ "version": "1.15.7",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
+ "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/http-errors": "*",
+ "@types/node": "*",
+ "@types/send": "*"
+ }
+ },
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
@@ -2230,6 +2332,19 @@
"node": ">=6.5"
}
},
+ "node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/acorn": {
"version": "8.14.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
@@ -2337,6 +2452,12 @@
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"license": "MIT"
},
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+ "license": "MIT"
+ },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -2388,6 +2509,45 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/body-parser": {
+ "version": "1.20.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
+ "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.5",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.13.0",
+ "raw-body": "2.5.2",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/body-parser/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/body-parser/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
"node_modules/bottleneck": {
"version": "2.19.5",
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
@@ -2445,6 +2605,44 @@
"ieee754": "^1.2.1"
}
},
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
+ "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
+ "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/chalk": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
@@ -2557,6 +2755,55 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
+ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+ "license": "MIT"
+ },
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
@@ -2604,6 +2851,25 @@
"node": ">=0.4.0"
}
},
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
"node_modules/diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
@@ -2625,6 +2891,26 @@
"url": "https://dotenvx.com"
}
},
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "license": "MIT"
+ },
"node_modules/emoji-regex": {
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
@@ -2632,6 +2918,15 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/environment": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz",
@@ -2645,6 +2940,51 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "license": "MIT"
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
@@ -2685,6 +3025,67 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
+ "node_modules/express": {
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.3",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.7.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.3.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.3",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.12",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.13.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.19.0",
+ "serve-static": "1.16.2",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/express/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/express/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
"node_modules/fast-content-type-parse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz",
@@ -2760,6 +3161,39 @@
"node": ">=8"
}
},
+ "node_modules/finalhandler": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
+ "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/finalhandler/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/finalhandler/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
"node_modules/form-data": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
@@ -2793,6 +3227,24 @@
"node": ">= 12.20"
}
},
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -2807,6 +3259,15 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/get-east-asian-width": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz",
@@ -2820,6 +3281,43 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/get-intrinsic": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
+ "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.0",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/get-stream": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
@@ -2855,6 +3353,18 @@
"node": ">=4"
}
},
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@@ -2865,6 +3375,46 @@
"node": ">=4"
}
},
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "license": "MIT",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/human-signals": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
@@ -2900,6 +3450,18 @@
"url": "https://github.com/sponsors/typicode"
}
},
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -2927,6 +3489,21 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -3167,6 +3744,33 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"license": "ISC"
},
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+ "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -3183,6 +3787,15 @@
"node": ">= 8"
}
},
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
@@ -3196,6 +3809,18 @@
"node": ">=8.6"
}
},
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -3273,6 +3898,15 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/neo4j-driver": {
"version": "5.27.0",
"resolved": "https://registry.npmjs.org/neo4j-driver/-/neo4j-driver-5.27.0.tgz",
@@ -3452,6 +4086,27 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
+ "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/octokit": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/octokit/-/octokit-4.1.0.tgz",
@@ -3473,6 +4128,18 @@
"node": ">= 18"
}
},
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/onetime": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
@@ -3530,6 +4197,15 @@
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"license": "MIT"
},
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/path-browserify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
@@ -3546,6 +4222,12 @@
"node": ">=8"
}
},
+ "node_modules/path-to-regexp": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
+ "license": "MIT"
+ },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -3613,6 +4295,19 @@
"fsevents": "2.3.3"
}
},
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/pstree.remy": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
@@ -3620,6 +4315,21 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/qs": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+ "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -3640,6 +4350,30 @@
],
"license": "MIT"
},
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -3772,6 +4506,12 @@
],
"license": "MIT"
},
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
+ },
"node_modules/semver": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
@@ -3785,6 +4525,75 @@
"node": ">=10"
}
},
+ "node_modules/send": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+ "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/send/node_modules/debug/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
+ "node_modules/send/node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
+ "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.19.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "license": "ISC"
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -3808,6 +4617,78 @@
"node": ">=8"
}
},
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/signal-exit": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
@@ -3876,6 +4757,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@@ -4040,6 +4930,15 @@
"node": ">=12"
}
},
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
"node_modules/touch": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
@@ -4140,6 +5039,19 @@
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "license": "MIT",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/typescript": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
@@ -4178,6 +5090,24 @@
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==",
"license": "ISC"
},
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
"node_modules/uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
@@ -4197,6 +5127,15 @@
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"license": "MIT"
},
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/web-streams-polyfill": {
"version": "4.0.0-beta.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz",
diff --git a/package.json b/package.json
index 52ac711..857a229 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,10 @@
"dependencies": {
"@aws-sdk/client-sqs": "^3.726.1",
"@prisma/client": "^6.2.1",
+ "@types/express": "^5.0.0",
+ "cors": "^2.8.5",
"dotenv": "^16.4.5",
+ "express": "^4.21.2",
"neo4j-driver": "^5.27.0",
"octokit": "^4.1.0",
"openai": "^4.73.1",
@@ -43,6 +46,7 @@
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
+ "@types/cors": "^2.8.17",
"@types/node": "^22.10.1",
"husky": "^9.1.6",
"lint-staged": "^15.2.10",
diff --git a/prisma b/prisma
index eaec1cd..59120fb 160000
--- a/prisma
+++ b/prisma
@@ -1 +1 @@
-Subproject commit eaec1cd27326af6b3fe4c2e67ab5aa5141afe0af
+Subproject commit 59120fb3be6aab5d490d1fc61c574bc055829203
diff --git a/scripts/commit-submodules.sh b/scripts/commit-submodules.sh
new file mode 100644
index 0000000..599ca84
--- /dev/null
+++ b/scripts/commit-submodules.sh
@@ -0,0 +1,24 @@
+cd prisma
+echo "Entering prisma submodule"
+git status
+git add . && npx git-cz
+git push &
+
+echo "Entering defs submodule"
+cd ../
+cd src/util/defs
+git status
+git add . && npx git-cz
+git push &
+
+cd ../../..
+
+git add prisma
+git add src/util/defs
+read -p "Enter a commit message (default 'Update Submodules'): " COMMITMSG
+
+if [[ -z $COMMITMSG ]]; then
+ COMMITMSG="Update submodules";
+fi
+
+git commit -m "$COMMITMSG"
\ No newline at end of file
diff --git a/scripts/pr-submodules.sh b/scripts/pr-submodules.sh
new file mode 100644
index 0000000..6361a23
--- /dev/null
+++ b/scripts/pr-submodules.sh
@@ -0,0 +1,21 @@
+if ! command -v gh &> /dev/null
+then
+ echo "gh is required to create pull requests from submodules";
+ exit 1;
+fi
+
+read -p "Enter the target pull request branch: " PULLBRANCH
+
+if [[ -z $PULLBRANCH ]]; then
+ echo "A target pull request branch is necessary!";
+ exit 1;
+fi
+
+cd prisma
+gh pr create -B $PULLBRANCH
+
+cd ../
+cd src/util/defs
+gh pr create -B $PULLBRANCH
+
+cd ../../../
\ No newline at end of file
diff --git a/scripts/update-submodules.sh b/scripts/update-submodules.sh
index 8d3dbe7..b60665f 100644
--- a/scripts/update-submodules.sh
+++ b/scripts/update-submodules.sh
@@ -1,13 +1,22 @@
PARENT_BRANCH=$(git branch --show-current)
cd prisma
-git checkout -b $PARENT_BRANCH
+if git show-ref --verify --quiet refs/heads/"$PARENT_BRANCH"; then
+ git checkout "$PARENT_BRANCH"
+else
+ git checkout -b "$PARENT_BRANCH"
+fi
+
git pull origin $PARENT_BRANCH
-git push origin $PARENT_BRANCH
+git push -u origin $PARENT_BRANCH
cd ..
cd src/util/defs
-git checkout -b $PARENT_BRANCH
+if git show-ref --verify --quiet refs/heads/"$PARENT_BRANCH"; then
+ git checkout "$PARENT_BRANCH"
+else
+ git checkout -b "$PARENT_BRANCH"
+fi
git pull origin $PARENT_BRANCH
-git push origin $PARENT_BRANCH
-cd ../../../
+git push -u origin $PARENT_BRANCH
+cd ../../../
\ No newline at end of file
diff --git a/src/common/depgraph/index.ts b/src/common/depgraph/index.ts
index 3a30dec..6467823 100644
--- a/src/common/depgraph/index.ts
+++ b/src/common/depgraph/index.ts
@@ -42,13 +42,17 @@ export class DependencyGraph implements IDependencyGraph {
moduleToSymbolDependencies: ModuleToSymbolDependency[]
moduleToModuleDependencies: ModuleToModuleDependency[]
- constructor() {
- this.symbolNodes = []
- this.moduleNodes = []
- this.symbolToSymbolDependencies = []
- this.symbolToModuleDependencies = []
- this.moduleToSymbolDependencies = []
- this.moduleToModuleDependencies = []
+ constructor(depGraph?: DependencyGraph) {
+ this.symbolNodes = depGraph?.symbolNodes ?? []
+ this.moduleNodes = depGraph?.moduleNodes ?? []
+ this.symbolToSymbolDependencies =
+ depGraph?.symbolToSymbolDependencies ?? []
+ this.symbolToModuleDependencies =
+ depGraph?.symbolToModuleDependencies ?? []
+ this.moduleToSymbolDependencies =
+ depGraph?.moduleToSymbolDependencies ?? []
+ this.moduleToModuleDependencies =
+ depGraph?.moduleToModuleDependencies ?? []
}
addSymbolNode(symbolNode: Symbol) {
diff --git a/src/eval-server/controllers/index.ts b/src/eval-server/controllers/index.ts
new file mode 100644
index 0000000..0320249
--- /dev/null
+++ b/src/eval-server/controllers/index.ts
@@ -0,0 +1,412 @@
+import { ContextGraph } from "@/common/ctxgraph"
+import { DependencyGraph } from "@/common/depgraph"
+import { type ParseArgs, createParser } from "@/common/parser"
+import entrypoints from "@/eval-server/entrypoints.json"
+import { loadCachedGraph, storeCachedGraph } from "@/eval-server/utils/cache"
+import db from "@/util/db"
+import { StatusCodes } from "@/util/defs/engraph-backend/common"
+import { LogLevel, log } from "@/util/log"
+import { isStatusCode } from "@/util/process"
+import type { PreferenceType, ProjectType } from "@prisma/client"
+import type { Request, Response } from "express"
+import fs from "fs/promises"
+import path from "path"
+
+export async function getSupportedParsers(req: Request, res: Response) {
+ try {
+ const evalCasesDirPath = path.join(process.cwd(), "eval-cases")
+ const evalCasesDir = await fs.readdir(evalCasesDirPath, {
+ withFileTypes: true,
+ })
+
+ const evalCasesParsers = evalCasesDir
+ .map((parserDir) => {
+ return parserDir.isDirectory() ? parserDir.name : null
+ })
+ .filter((parserDir) => {
+ return parserDir !== null
+ })
+
+ res.status(200).json({
+ supportedParsers: evalCasesParsers,
+ })
+ } catch (e) {
+ log("eval-server", LogLevel.Error, e)
+ res.status(StatusCodes.INTERNAL_ERROR).json({})
+ }
+}
+
+export async function getParserProjects(req: Request, res: Response) {
+ try {
+ const parserName = req.params.parser
+ const parserDirPath = path.join(process.cwd(), "eval-cases", parserName)
+ const parserDir = await fs.readdir(parserDirPath, {
+ withFileTypes: true,
+ })
+
+ const evalProjects = parserDir
+ .map((parserProject) => {
+ return parserProject.isDirectory() ? parserProject.name : null
+ })
+ .filter((parserProject) => {
+ return parserProject !== null
+ })
+
+ res.status(200).json({
+ supportedProjects: evalProjects,
+ })
+ } catch (e) {
+ log("eval-server", LogLevel.Error, e)
+ res.status(StatusCodes.INTERNAL_ERROR).json({})
+ }
+}
+
+export async function getProjectModules(req: Request, res: Response) {
+ try {
+ const parserName = req.params.parser
+ const projectName = req.params.project
+
+ const entryPoint =
+ // @ts-expect-error
+ (entrypoints[parserName][projectName] as string) ?? ""
+
+ const parseArgs: ParseArgs = {
+ projectType: parserName as ProjectType,
+ projectEntryPoint: entryPoint,
+ projectPath: path.join(
+ process.cwd(),
+ "eval-cases",
+ parserName,
+ projectName,
+ ),
+ }
+
+ const parserInstance = await createParser(parseArgs)
+
+ if (isStatusCode(parserInstance)) {
+ res.status(500).json({})
+ return
+ }
+
+ await parserInstance.parseProject()
+
+ const dependencyGraph = parserInstance.getDependencyGraph()
+
+ const { moduleNodes } = dependencyGraph
+
+ res.status(StatusCodes.OK).json({
+ moduleNodes: moduleNodes,
+ })
+ } catch (e) {
+ log("eval-server", LogLevel.Error, e)
+ res.status(StatusCodes.INTERNAL_ERROR).json({})
+ }
+}
+
+export async function getProjectSymbols(req: Request, res: Response) {
+ try {
+ const parserName = req.params.parser
+ const projectName = req.params.project
+
+ const entryPoint =
+ // @ts-expect-error
+ (entrypoints[parserName][projectName] as string) ?? ""
+
+ const parseArgs: ParseArgs = {
+ projectType: parserName as ProjectType,
+ projectEntryPoint: entryPoint,
+ projectPath: path.join(
+ process.cwd(),
+ "eval-cases",
+ parserName,
+ projectName,
+ ),
+ }
+
+ const parserInstance = await createParser(parseArgs)
+
+ if (isStatusCode(parserInstance)) {
+ res.status(500).json({})
+ return
+ }
+
+ await parserInstance.parseProject()
+
+ const dependencyGraph = parserInstance.getDependencyGraph()
+
+ const { symbolNodes } = dependencyGraph
+
+ res.status(StatusCodes.OK).json({
+ symbolNodes: symbolNodes,
+ })
+ } catch (e) {
+ log("eval-server", LogLevel.Error, e)
+ res.status(StatusCodes.INTERNAL_ERROR).json({})
+ }
+}
+
+export async function getProjectModuleEvalResult(req: Request, res: Response) {
+ try {
+ const parserName = req.params.parser
+ const projectName = req.params.project
+ const moduleName = req.query.module as string
+
+ const entryPoint =
+ // @ts-expect-error
+ (entrypoints[parserName][projectName] as string) ?? ""
+
+ const parseArgs: ParseArgs = {
+ projectType: parserName as ProjectType,
+ projectEntryPoint: entryPoint,
+ projectPath: path.join(
+ process.cwd(),
+ "eval-cases",
+ parserName,
+ projectName,
+ ),
+ }
+
+ let dependencyGraph = loadCachedGraph(parserName, projectName)
+
+ if (dependencyGraph === null) {
+ const parserInstance = await createParser(parseArgs)
+
+ if (isStatusCode(parserInstance)) {
+ res.status(StatusCodes.INTERNAL_ERROR).json({})
+ return
+ }
+
+ await parserInstance.parseProject()
+ dependencyGraph = parserInstance.getDependencyGraph()
+ }
+
+ dependencyGraph.moduleNodes = dependencyGraph.moduleNodes.map(
+ (moduleNode) => {
+ if (moduleNode.modulePath === moduleName) {
+ moduleNode.moduleSummary = undefined
+ }
+ return moduleNode
+ },
+ )
+
+ const moduleNode = dependencyGraph.getModuleNode(moduleName)
+
+ if (moduleNode === undefined) {
+ res.status(StatusCodes.NOT_FOUND).json({})
+ return
+ }
+
+ const { modulePath, moduleSourceCode } = moduleNode
+
+ const contextGraph = new ContextGraph(parseArgs, dependencyGraph)
+
+ const dependencyGraphClone = new DependencyGraph(dependencyGraph)
+
+ // Remove all dependencies of the given module
+ dependencyGraphClone.moduleToModuleDependencies =
+ dependencyGraphClone.moduleToModuleDependencies.filter(
+ (moduleToModuleDependency) => {
+ return (
+ moduleToModuleDependency.dependentModulePath !==
+ modulePath
+ )
+ },
+ )
+ dependencyGraphClone.moduleToSymbolDependencies =
+ dependencyGraphClone.moduleToSymbolDependencies.filter(
+ (moduleToSymbolDependency) => {
+ return (
+ moduleToSymbolDependency.dependentModulePath !==
+ modulePath
+ )
+ },
+ )
+
+ const cloneGraph = new ContextGraph(parseArgs, dependencyGraphClone)
+
+ await Promise.all([
+ contextGraph.generateSummaryForModule(modulePath),
+ cloneGraph.generateSummaryForModule(modulePath),
+ ])
+
+ storeCachedGraph(parserName, projectName, contextGraph.dependencyGraph)
+
+ const contextSummary =
+ contextGraph.dependencyGraph.getModuleNode(modulePath)
+ ?.moduleSummary ?? ""
+ const plainSummary =
+ cloneGraph.dependencyGraph.getModuleNode(modulePath)
+ ?.moduleSummary ?? ""
+
+ const evalSummary = await db.evalSummary.create({
+ data: {
+ summaryType: parserName as ProjectType,
+ summaryProject: projectName,
+ summarySource: moduleSourceCode,
+ summaryContext: contextSummary,
+ summaryPlain: plainSummary,
+ summaryTimestamp: new Date(),
+ },
+ })
+
+ res.status(StatusCodes.OK).json(evalSummary)
+ } catch (e) {
+ log("eval-server", LogLevel.Error, e)
+ res.status(StatusCodes.INTERNAL_ERROR).json({})
+ }
+}
+
+export async function getProjectSymbolEvalResult(req: Request, res: Response) {
+ try {
+ const parserName = req.params.parser
+ const projectName = req.params.project
+ const symbolPath = req.query.path as string
+ const symbolIdentifier = req.query.identifier as string
+
+ const entryPoint =
+ // @ts-expect-error
+ (entrypoints[parserName][projectName] as string) ?? ""
+
+ const parseArgs: ParseArgs = {
+ projectType: parserName as ProjectType,
+ projectEntryPoint: entryPoint,
+ projectPath: path.join(
+ process.cwd(),
+ "eval-cases",
+ parserName,
+ projectName,
+ ),
+ }
+
+ let dependencyGraph = loadCachedGraph(parserName, projectName)
+
+ if (dependencyGraph === null) {
+ const parserInstance = createParser(parseArgs)
+
+ if (isStatusCode(parserInstance)) {
+ res.status(StatusCodes.INTERNAL_ERROR).json({})
+ return
+ }
+
+ await parserInstance.parseProject()
+ dependencyGraph = parserInstance.getDependencyGraph()
+ }
+
+ dependencyGraph.symbolNodes = dependencyGraph.symbolNodes.map(
+ (symbolNode) => {
+ if (
+ symbolNode.symbolPath === symbolPath &&
+ symbolNode.symbolIdentifier === symbolIdentifier
+ ) {
+ symbolNode.symbolSummary = undefined
+ }
+ return symbolNode
+ },
+ )
+
+ const symbolNode = dependencyGraph.getSymbolNode(
+ symbolPath,
+ symbolIdentifier,
+ )
+
+ if (symbolNode === undefined) {
+ res.status(StatusCodes.NOT_FOUND).json({})
+ return
+ }
+
+ const { symbolSourceCode } = symbolNode
+
+ const contextGraph = new ContextGraph(parseArgs, dependencyGraph)
+
+ const dependencyGraphClone = new DependencyGraph(dependencyGraph)
+
+ // Remove all dependencies of the given symbol
+ dependencyGraphClone.symbolToModuleDependencies =
+ dependencyGraphClone.symbolToModuleDependencies.filter(
+ (symbolToModuleDependency) => {
+ if (
+ symbolToModuleDependency.dependentSymbolPath ===
+ symbolPath &&
+ symbolToModuleDependency.dependentSymbolIdentifier ===
+ symbolIdentifier
+ ) {
+ return false
+ }
+ return true
+ },
+ )
+ dependencyGraphClone.symbolToSymbolDependencies =
+ dependencyGraphClone.symbolToSymbolDependencies.filter(
+ (symbolToSymbolDependency) => {
+ if (
+ symbolToSymbolDependency.dependentSymbolPath ===
+ symbolPath &&
+ symbolToSymbolDependency.dependentSymbolIdentifier ===
+ symbolIdentifier
+ ) {
+ return false
+ }
+ return true
+ },
+ )
+
+ const cloneGraph = new ContextGraph(parseArgs, dependencyGraphClone)
+
+ await Promise.all([
+ contextGraph.generateSummaryForSymbol(symbolPath, symbolIdentifier),
+ cloneGraph.generateSummaryForSymbol(symbolPath, symbolIdentifier),
+ ])
+
+ storeCachedGraph(parserName, projectName, contextGraph.dependencyGraph)
+
+ const contextSummary =
+ contextGraph.dependencyGraph.getSymbolNode(
+ symbolPath,
+ symbolIdentifier,
+ )?.symbolSummary ?? ""
+
+ const plainSummary =
+ cloneGraph.dependencyGraph.getSymbolNode(
+ symbolPath,
+ symbolIdentifier,
+ )?.symbolSummary ?? ""
+
+ const evalSummary = await db.evalSummary.create({
+ data: {
+ summaryType: parserName as ProjectType,
+ summaryProject: projectName,
+ summarySource: symbolSourceCode,
+ summaryContext: contextSummary,
+ summaryPlain: plainSummary,
+ summaryTimestamp: new Date(),
+ },
+ })
+
+ res.status(StatusCodes.OK).json(evalSummary)
+ } catch (e) {
+ log("eval-server", LogLevel.Error, e)
+ res.status(StatusCodes.INTERNAL_ERROR).json({})
+ }
+}
+
+export async function addEvalPreference(req: Request, res: Response) {
+ try {
+ const { evalId, preferenceType } = req.body
+
+ if (!evalId || !preferenceType) {
+ res.status(StatusCodes.BAD_REQUEST).json({})
+ return
+ }
+
+ await db.evalSummaryPreference.create({
+ data: {
+ preferenceSummaryId: evalId as string,
+ preferenceType: preferenceType as PreferenceType,
+ preferenceTimestamp: new Date(),
+ },
+ })
+ } catch (e) {
+ log("eval-server", LogLevel.Error, e)
+ res.status(StatusCodes.INTERNAL_ERROR).json({})
+ }
+}
diff --git a/src/eval-server/entrypoints.json b/src/eval-server/entrypoints.json
new file mode 100644
index 0000000..2c45841
--- /dev/null
+++ b/src/eval-server/entrypoints.json
@@ -0,0 +1,7 @@
+{
+ "typescript": {
+ "1-basic-imports": "",
+ "2-poisoned-source": "",
+ "3-portfolio-website": ""
+ }
+}
diff --git a/src/eval-server/index.ts b/src/eval-server/index.ts
new file mode 100644
index 0000000..c5a6671
--- /dev/null
+++ b/src/eval-server/index.ts
@@ -0,0 +1,25 @@
+// Watch out this is gonna get pretty big
+// We will be spinning up a small express server to pick up a random project
+import { indexRouter } from "@/eval-server/routers"
+import { EVAL_PORT } from "@/util/config/eval-server"
+import { LogLevel, log } from "@/util/log"
+import cors from "cors"
+import express from "express"
+
+export async function evalServerImpl() {
+ const evalServer = express()
+
+ evalServer.use(cors({ origin: "*" }))
+
+ evalServer.use(express.json())
+
+ evalServer.use("/api/v1", indexRouter)
+
+ evalServer.listen(EVAL_PORT, () => {
+ log(
+ "eval-server",
+ LogLevel.Debug,
+ `eval-server listening on port ${EVAL_PORT}`,
+ )
+ })
+}
diff --git a/src/eval-server/routers/index.ts b/src/eval-server/routers/index.ts
new file mode 100644
index 0000000..e13b698
--- /dev/null
+++ b/src/eval-server/routers/index.ts
@@ -0,0 +1,29 @@
+import {
+ addEvalPreference,
+ getParserProjects,
+ getProjectModuleEvalResult,
+ getProjectModules,
+ getProjectSymbolEvalResult,
+ getProjectSymbols,
+ getSupportedParsers,
+} from "@/eval-server/controllers"
+import { Router } from "@/eval-server/utils/router"
+
+const indexRouter = Router()
+
+indexRouter.get("/parsers", getSupportedParsers)
+indexRouter.get("/parsers/:parser/projects", getParserProjects)
+indexRouter.get("/parsers/:parser/projects/:project/modules", getProjectModules)
+indexRouter.get("/parsers/:parser/projects/:project/symbols", getProjectSymbols)
+indexRouter.get(
+ "/parsers/:parser/projects/:project/modules/eval",
+ getProjectModuleEvalResult,
+)
+indexRouter.get(
+ "/parsers/:parser/projects/:project/symbols/eval",
+ getProjectSymbolEvalResult,
+)
+
+indexRouter.post("/prefs", addEvalPreference)
+
+export { indexRouter }
diff --git a/src/eval-server/utils/cache.ts b/src/eval-server/utils/cache.ts
new file mode 100644
index 0000000..141634b
--- /dev/null
+++ b/src/eval-server/utils/cache.ts
@@ -0,0 +1,39 @@
+import { DependencyGraph } from "@/common/depgraph"
+import fs from "fs"
+import path from "path"
+
+export function loadCachedGraph(parser: string, project: string) {
+ const cacheLocation = path.join(
+ process.cwd(),
+ "cache",
+ parser,
+ project,
+ "graph.json",
+ )
+
+ try {
+ fs.statSync(cacheLocation)
+ } catch (e) {
+ return null
+ }
+
+ const fileContents = fs.readFileSync(cacheLocation, { encoding: "utf-8" })
+ const dependencyGraphData = JSON.parse(fileContents) as DependencyGraph
+ return new DependencyGraph(dependencyGraphData)
+}
+
+export function storeCachedGraph(
+ parser: string,
+ project: string,
+ graph: DependencyGraph,
+) {
+ const cacheDirLocation = path.join(process.cwd(), "cache", parser, project)
+
+ fs.mkdirSync(cacheDirLocation, { recursive: true })
+
+ const cacheLocation = path.join(cacheDirLocation, "graph.json")
+
+ const graphSnapshot = JSON.stringify(graph)
+
+ fs.writeFileSync(cacheLocation, graphSnapshot, {})
+}
diff --git a/src/eval-server/utils/router.ts b/src/eval-server/utils/router.ts
new file mode 100644
index 0000000..b31ef64
--- /dev/null
+++ b/src/eval-server/utils/router.ts
@@ -0,0 +1,5 @@
+import { Router as ExpressRouter } from "express"
+
+export function Router() {
+ return ExpressRouter({ mergeParams: true })
+}
diff --git a/src/index.ts b/src/index.ts
index d2f09d5..5e49138 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,45 +1,28 @@
-import { MESSAGE_COOLDOWN_MS } from "@/util/config/worker"
+import { evalServerImpl } from "@/eval-server"
+import { envVar } from "@/util/env"
import { LogLevel, log } from "@/util/log"
-import { StatusCode } from "@/util/process"
-import { deleteSQSMessage, receiveSQSMessage } from "@/util/sqs"
-import { timeout } from "@/util/time"
-import { startWorkflow } from "@/util/worker"
+import { workerImpl } from "@/worker"
import dotenv from "dotenv"
dotenv.config()
-async function workerImpl() {
+const MODE = envVar("MODE")
+
+if (MODE === "worker") {
+ workerImpl()
+} else if (MODE === "eval-server") {
+ evalServerImpl()
+} else {
+ log(
+ "process",
+ LogLevel.Error,
+ `Unexpected MODE (${MODE}). The process will now do nothing`,
+ )
while (true) {
- const workflowData = await receiveSQSMessage()
- if (workflowData === null) {
- log("worker", LogLevel.Debug, "No message received from SQS")
- } else {
- log(
- "worker",
- LogLevel.Info,
- "Received message from SQS",
- workflowData,
- )
-
- await deleteSQSMessage(workflowData.recvHandle)
- const workflowStatus = await startWorkflow({
- workflowId: workflowData.workflowId,
- })
-
- const reverseLookup = Object.keys(StatusCode)
-
- log(
- "worker",
- LogLevel.Info,
- `Workflow ${workflowData.workflowId} exited with status code ${reverseLookup[workflowStatus]}`,
- )
- }
- await timeout(MESSAGE_COOLDOWN_MS)
+ // Quite literally, do nothing!
}
}
-workerImpl()
-
// async function main() {
// const parserArgs = {
// projectEntryPoint: "",
diff --git a/src/parsers/typescript/index.ts b/src/parsers/typescript/index.ts
index 9cddb1a..5660bfd 100644
--- a/src/parsers/typescript/index.ts
+++ b/src/parsers/typescript/index.ts
@@ -90,20 +90,17 @@ class TypescriptParser extends Parser {
const namedImports = importDeclaration.getNamedImports()
namedImports.forEach((namedImport) => {
const symbolName = namedImport.getText()
- this.dependencyGraph.addSymbolToModuleDependency({
- dependencyModulePath: relativeFilePath,
- dependentSymbolIdentifier: symbolName,
- dependentSymbolPath: modulePath,
+ this.dependencyGraph.addModuleToSymbolDependency({
+ dependentModulePath: relativeFilePath,
+ dependencySymbolIdentifier: symbolName,
+ dependencySymbolPath: modulePath,
})
})
- const defaultImport = importDeclaration.getDefaultImport()
- if (defaultImport) {
- this.dependencyGraph.addModuleToModuleDependency({
- dependencyModulePath: modulePath,
- dependentModulePath: relativeFilePath,
- })
- }
+ this.dependencyGraph.addModuleToModuleDependency({
+ dependencyModulePath: modulePath,
+ dependentModulePath: relativeFilePath,
+ })
})
// Exports
diff --git a/src/util/config/eval-server.ts b/src/util/config/eval-server.ts
new file mode 100644
index 0000000..cbda9c6
--- /dev/null
+++ b/src/util/config/eval-server.ts
@@ -0,0 +1,3 @@
+import { envVar } from "@/util/env"
+
+export const EVAL_PORT = envVar("EVAL_PORT")
diff --git a/src/util/defs b/src/util/defs
index d93c090..b1fed48 160000
--- a/src/util/defs
+++ b/src/util/defs
@@ -1 +1 @@
-Subproject commit d93c0907d22cd3d0233690ef287dd71f930de9d2
+Subproject commit b1fed48cb35415b64a841ebd68082b31080e8252
diff --git a/src/worker/index.ts b/src/worker/index.ts
new file mode 100644
index 0000000..f7433f8
--- /dev/null
+++ b/src/worker/index.ts
@@ -0,0 +1,36 @@
+import { MESSAGE_COOLDOWN_MS } from "@/util/config/worker"
+import { LogLevel, log } from "@/util/log"
+import { StatusCode } from "@/util/process"
+import { deleteSQSMessage, receiveSQSMessage } from "@/util/sqs"
+import { timeout } from "@/util/time"
+import { startWorkflow } from "@/util/worker"
+
+export async function workerImpl() {
+ while (true) {
+ const workflowData = await receiveSQSMessage()
+ if (workflowData === null) {
+ log("worker", LogLevel.Debug, "No message received from SQS")
+ } else {
+ log(
+ "worker",
+ LogLevel.Info,
+ "Received message from SQS",
+ workflowData,
+ )
+
+ await deleteSQSMessage(workflowData.recvHandle)
+ const workflowStatus = await startWorkflow({
+ workflowId: workflowData.workflowId,
+ })
+
+ const reverseLookup = Object.keys(StatusCode)
+
+ log(
+ "worker",
+ LogLevel.Info,
+ `Workflow ${workflowData.workflowId} exited with status code ${reverseLookup[workflowStatus]}`,
+ )
+ }
+ await timeout(MESSAGE_COOLDOWN_MS)
+ }
+}
diff --git a/tests/typescript/3-complex-implementation/tsconfig.json b/tests/typescript/3-complex-implementation/tsconfig.json
deleted file mode 100644
index 3593edd..0000000
--- a/tests/typescript/3-complex-implementation/tsconfig.json
+++ /dev/null
@@ -1,124 +0,0 @@
-{
- "compilerOptions": {
- /* Visit https://aka.ms/tsconfig to read more about this file */
-
- /* Projects */
- // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
- // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
- // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
- // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
- // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
- // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
-
- /* Language and Environment */
- "target": "ESNext",
- /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
- // "lib": ["ESNext"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
- // "jsx": "preserve", /* Specify what JSX code is generated. */
- // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
- // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
- // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
- // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
- // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
- // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
- // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
- // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
- // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
-
- /* Modules */
- "module": "NodeNext",
- /* Specify what module code is generated. */
- "rootDir": "./" /* Specify the root folder within your source files. */,
- "moduleResolution": "NodeNext",
- /* Specify how TypeScript looks up a file from a given module specifier. */
- "baseUrl": ".",
- /* Specify the base directory to resolve non-relative module names. */
- "paths": {
- "@/*": ["*"]
- },
- /* Specify a set of entries that re-map imports to additional lookup locations. */
- // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
- // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
- // "types": [], /* Specify type package names to be included without being referenced in a source file. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
- // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
- // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
- // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
- // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
- // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
- "resolveJsonModule": true /* Enable importing .json files. */,
- // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
- // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
-
- /* JavaScript Support */
- // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
- // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
- // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
-
- /* Emit */
- // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
- // "declarationMap": true, /* Create sourcemaps for d.ts files. */
- // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
- // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
- // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
- // "outFile": "./dist/index", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
- // "outDir": "./dist",
- /* Specify an output folder for all emitted files. */
- // "removeComments": true,
- /* Disable emitting comments. */
- // "noEmit": true, /* Disable emitting files from a compilation. */
- /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
- // "importHelpers": true,
- /* Specify emit/checking behavior for imports that are only used for types. */
- "importsNotUsedAsValues": "remove",
- // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
- // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
- // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
- // "newLine": "crlf", /* Set the newline character for emitting files. */
- // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
- // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
- // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
- // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
- // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
- // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
-
- /* Interop Constraints */
- // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
- // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
- // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
- "esModuleInterop": true,
- /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
- // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
- "forceConsistentCasingInFileNames": true,
- /* Ensure that casing is correct in imports. */
-
- /* Type Checking */
- "strict": true,
- /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
- // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
- // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
- // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
- // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
- // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
- // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
- // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
- // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
- // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
- // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
- // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
- // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
- // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
- // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
-
- /* Completeness */
- // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
- "skipLibCheck": true
- /* Skip type checking all .d.ts files. */
- }
-}