Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,639 changes: 26 additions & 1,613 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 3 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,17 @@
"dependencies": {
"@antv/g6": "^5.0.49",
"@duckdb/duckdb-wasm": "1.29.0",
"@popperjs/core": "^2.11.8",
"@ladybugdb/core": "0.16.1",
"@ladybugdb/wasm-core": "0.16.1",
"antlr4-c3": "3.2.3",
"antlr4ng": "1.0.7",
"axios": "^1.16.1",
"bootstrap": "^5.3.1",
"chroma-js": "^3.0.0",
"core-js": "^3.8.3",
"cors": "^2.8.5",
"dropzone": "^6.0.0-beta.2",
"express": "^4.22.2",
"@ladybugdb/core": "0.16.1",
"@ladybugdb/wasm-core": "0.16.1",
"moment": "^2.29.4",
"monaco-editor": "^0.41.0",
"monaco-themes": "^0.4.4",
"multer": "^2.1.1",
"openai": "^4.20.1",
"pinia": "^2.0.23",
"pino": "^8.16.1",
"pino-pretty": "^10.2.3",
"sqlite": "^5.1.1",
"sqlite3": "^6.0.1",
"uuid": "^14.0.0",
"vue": "^3.2.13",
"node-gyp": "^12.1.0"
"vue": "^3.2.13"
},
"devDependencies": {
"@babel/core": "^7.12.16",
Expand Down
10 changes: 0 additions & 10 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,12 @@

<script>
import MainLayout from "./components/MainLayout.vue";
import { Tooltip } from "bootstrap";

export default {
name: "App",
components: {
MainLayout,
},
mounted() {
this.tooltip = new Tooltip(document.body, {
selector: "[data-bs-toggle='tooltip']",
trigger: "hover",
});
},
beforeUnmount() {
this.tooltip.dispose();
},
};
</script>

Expand Down
8 changes: 3 additions & 5 deletions src/components/ImporterView/ImporterMainView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@

<script lang="js">
import Axios from "@/utils/AxiosWrapper";
import { v4 as uuidv4 } from 'uuid';
import { uuidv4 } from "@/utils/UniqueId";
import { mapStores } from 'pinia';
import { useModeStore } from '../../store/ModeStore';
import { DATA_TYPES, IMPORT_ACTIONS, JOB_STATUS } from '../../utils/Constants';
Expand Down Expand Up @@ -791,11 +791,9 @@ export default {
try {
if (!this.modeStore.isWasm) {
const api = `/api/import/${this.currentJob.jobId}/${virtualFileName}`;
const formData = new FormData();
formData.append('file', file.file);
await Axios.post(api, formData, {
await Axios.post(api, file.file, {
headers: {
'Content-Type': 'multipart/form-data',
'Content-Type': 'application/octet-stream',
}
});
} else {
Expand Down
31 changes: 5 additions & 26 deletions src/components/ImporterView/ImporterViewDropZone.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
ref="dropzone"
for="files"
class="dropzone-container"
@dragover.prevent
@drop.prevent="handleDrop"
>
<div class="file-icon"><i class="fa-solid fa-file-circle-plus text-[(var(--bs-body-bg-accent))]" /></div>
<div class="d-flex flex-column align-items-center text-center pt-3 px-5">
Expand Down Expand Up @@ -48,39 +50,16 @@
</template>

<script lang="js">
import Dropzone from "dropzone";

export default {
name: "ImporterViewDropZone",
emits: ["filesSelected", "loadBundledDataset"],
data() {
return {
dropzone: null,
};
},

mounted() {
this.dropzone = new Dropzone(this.$refs.dropzone, {
url: "/",
autoProcessQueue: false,
uploadMultiple: true,
disablePreviews: true,
});
this.dropzone.on("drop", (e) => {
e.preventDefault();
const files = e.dataTransfer.files;
this.$emit("filesSelected", files);
});
},

beforeUnmount() {
this.dropzone.destroy();
},

methods: {
selectFiles() {
this.$refs.fileInput.click();
},
handleDrop(e) {
this.$emit("filesSelected", e.dataTransfer.files);
},
handleFilesSelected(e) {
const files = e.target.files;
this.$emit("filesSelected", files);
Expand Down
17 changes: 5 additions & 12 deletions src/components/ImporterView/ImporterViewSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<div
ref="sidebar"
class="importer-sidebar"
@dragover.prevent
@drop.prevent="handleDrop"
>
<button
class="importer-sidebar__btn"
Expand Down Expand Up @@ -127,7 +129,6 @@
</template>

<script lang="js">
import Dropzone from "dropzone";
import { Modal } from 'bootstrap';
export default {
name: "ImporterViewSidebar",
Expand All @@ -152,17 +153,6 @@ export default {
mounted() {
this.modal = new Modal(this.$refs.modal);
this.$refs.modal.addEventListener("hidden.bs.modal", this.cancelFileRemoval);
this.dropzone = new Dropzone(this.$refs.sidebar, {
url: "/",
autoProcessQueue: false,
uploadMultiple: true,
disablePreviews: true,
});
this.dropzone.on("drop", (e) => {
e.preventDefault();
const files = e.dataTransfer.files;
this.$emit("dropFiles", files);
});
},
beforeUnmount() {
this.modal.dispose();
Expand Down Expand Up @@ -194,6 +184,9 @@ export default {
setCsvFormat(file) {
this.$emit("setCsvFormat", file);
},
handleDrop(e) {
this.$emit("dropFiles", e.dataTransfer.files);
},
hideModal() {
this.modal.hide();
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/SchemaView/SchemaSidebarAddView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ import { useSettingsStore } from "../../store/SettingsStore";
import { mapStores } from 'pinia'
import SchemaPropertyEditCell from "./SchemaPropertyEditCell.vue";
import { DATA_TYPES, PLACEHOLDER_NODE_TABLE, PLACEHOLDER_REL_TABLE } from "../../utils/Constants";
import { v4 as uuidv4 } from "uuid";
import { uuidv4 } from "@/utils/UniqueId";
export default {
name: "SchemaSidebarAddView",
components: {
Expand Down
2 changes: 1 addition & 1 deletion src/components/ShellView/ShellMainView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

<script lang="js">
import ShellCell from "./ShellCell.vue";
import { v4 as uuidv4 } from 'uuid';
import { uuidv4 } from "@/utils/UniqueId";
import Axios from "@/utils/AxiosWrapper";
import { MODES } from "@/utils/Constants";
export default {
Expand Down
1 change: 0 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";
import "bootstrap/scss/bootstrap.scss";
import "bootstrap";
import "./assets/global.css";

const pinia = createPinia();
Expand Down
39 changes: 19 additions & 20 deletions src/server/Import.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,24 @@
const express = require("express");
const router = express.Router();
const path = require("path");
const multer = require("multer");
const fs = require("fs/promises");
const database = require("./utils/Database");
const uuid = require("uuid");
const DataImportUtils = require("../utils/DataImport");
const DataImportFsUtils = require("./utils/DataImportFs");
const Constants = require("./utils/Constants");
const JOB_STATUS = Constants.JOB_STATUS;
const IMPORT_ACTIONS = Constants.IMPORT_ACTIONS;
const ddl = require("../utils/DataDefinitionLanguage");


const jobsMap = new Map();

const storage = multer.diskStorage({
destination: function (req, _, cb) {
const jobId = req.params.job_id;
const tmpDirPath = DataImportFsUtils.getTmpPath(jobId);
cb(null, tmpDirPath);
},
filename: function (req, _, cb) {
cb(null, req.params.file_name);
},
});

const upload = multer({ storage });
function isValidUuid(value) {
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
}

router.post("/:job_id", async (req, res) => {
const jobId = req.params.job_id;
if (!jobId || !uuid.validate(jobId)) {
if (!jobId || !isValidUuid(jobId)) {
return res.status(400).send({
success: false,
errors: ["Missing or invalid job ID"]
Expand Down Expand Up @@ -76,7 +65,7 @@ router.post("/:job_id", async (req, res) => {

router.post("/:job_id/exec", async (req, res) => {
const jobId = req.params.job_id;
if (!jobId || !uuid.validate(jobId)) {
if (!jobId || !isValidUuid(jobId)) {
return res.status(400).send({ error: "Missing or invalid job ID" });
}
const job = jobsMap.get(jobId);
Expand Down Expand Up @@ -156,10 +145,13 @@ router.post("/:job_id/exec", async (req, res) => {
}
});

router.post("/:job_id/:file_name", upload.single("file"), async (req, res) => {
router.post("/:job_id/:file_name", express.raw({
type: "application/octet-stream",
limit: "2gb",
}), async (req, res) => {
const jobId = req.params.job_id;
const fileName = req.params.file_name;
if (!jobId || !uuid.validate(jobId)) {
if (!jobId || !isValidUuid(jobId)) {
return res.status(400).send({ error: "Missing or invalid job ID" });
}
if (!fileName) {
Expand All @@ -171,6 +163,13 @@ router.post("/:job_id/:file_name", upload.single("file"), async (req, res) => {
}
for (const step of job.plan) {
if (step.action === IMPORT_ACTIONS.UPLOAD && step.fileName === fileName) {
const tmpDirPath = DataImportFsUtils.getTmpPath(jobId);
const filePath = path.join(tmpDirPath, fileName);
try {
await fs.writeFile(filePath, req.body);
} catch (err) {
return res.status(500).send({ error: "Error writing uploaded file" });
}
step.status = JOB_STATUS.SUCCESS;
return res.status(200).send({ success: true });
}
Expand All @@ -180,7 +179,7 @@ router.post("/:job_id/:file_name", upload.single("file"), async (req, res) => {

router.get("/:job_id", async (req, res) => {
const jobId = req.params.job_id;
if (!jobId || !uuid.validate(jobId)) {
if (!jobId || !isValidUuid(jobId)) {
return res.status(400).send({ error: "Missing or invalid job ID" });
}
const job = jobsMap.get(jobId);
Expand Down
8 changes: 6 additions & 2 deletions src/server/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const express = require("express");
const cors = require("cors");
const api = require("./API");
const path = require("path");
const process = require("process");
Expand All @@ -23,7 +22,12 @@ process.on("SIGTERM", () => {

const app = express();
if (CROSS_ORIGIN) {
app.use(cors());
app.use((_, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
next();
});
logger.info("CORS enabled for all origins");
}
const PORT = process.env.PORT ? parseInt(process.env.PORT) : 8000;
Expand Down
30 changes: 21 additions & 9 deletions src/server/utils/Logger.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
const pino = require("pino");
const logger = pino({
transport: {
target: "pino-pretty",
options: {
colorize: true,
},
function log(level, message) {
const output = `[${new Date().toISOString()}] ${level}: ${message}`;
if (level === "error") {
console.error(output);
} else if (level === "warn") {
console.warn(output);
} else {
console.log(output);
}
}

module.exports = {
info(message) {
log("info", message);
},
});
module.exports = logger;
warn(message) {
log("warn", message);
},
error(message) {
log("error", message);
},
};
Loading
Loading