mirror of
https://github.com/drawdb-io/drawdb.git
synced 2025-09-16 03:02:43 +00:00
poc
This commit is contained in:
9
package-lock.json
generated
9
package-lock.json
generated
@@ -19,6 +19,7 @@
|
|||||||
"axios": "^1.7.4",
|
"axios": "^1.7.4",
|
||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"dexie": "^3.2.4",
|
"dexie": "^3.2.4",
|
||||||
|
"dexie-observable": "^4.0.1-beta.13",
|
||||||
"dexie-react-hooks": "^1.1.7",
|
"dexie-react-hooks": "^1.1.7",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"framer-motion": "^10.18.0",
|
"framer-motion": "^10.18.0",
|
||||||
@@ -3053,6 +3054,14 @@
|
|||||||
"node": ">=6.0"
|
"node": ">=6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dexie-observable": {
|
||||||
|
"version": "4.0.1-beta.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/dexie-observable/-/dexie-observable-4.0.1-beta.13.tgz",
|
||||||
|
"integrity": "sha512-axmgPk7yjoPwj+0DdQIE5s1MBXi+6XcIFIjBKdQAmSGpsLQSth/LHvMOQ3q3Wj6pwIE5hqIxg2GL75sVqQbhEw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"dexie": "^3.0.2 || ^4.0.1-alpha.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dexie-react-hooks": {
|
"node_modules/dexie-react-hooks": {
|
||||||
"version": "1.1.7",
|
"version": "1.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/dexie-react-hooks/-/dexie-react-hooks-1.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/dexie-react-hooks/-/dexie-react-hooks-1.1.7.tgz",
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
"axios": "^1.7.4",
|
"axios": "^1.7.4",
|
||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"dexie": "^3.2.4",
|
"dexie": "^3.2.4",
|
||||||
|
"dexie-observable": "^4.0.1-beta.13",
|
||||||
"dexie-react-hooks": "^1.1.7",
|
"dexie-react-hooks": "^1.1.7",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"framer-motion": "^10.18.0",
|
"framer-motion": "^10.18.0",
|
||||||
|
80
server/index.js
Normal file
80
server/index.js
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const cors = require('cors')
|
||||||
|
const path = require('path');
|
||||||
|
const app = express();
|
||||||
|
const fs = require('node:fs');
|
||||||
|
|
||||||
|
const DRAWDB_FILE_DIR = process.env.DRAWDB_FILE_DIR || '/usercode'
|
||||||
|
const DRAWDB_HOME = process.env.DRAWDB_HOME || path.join(__dirname, '../dist');
|
||||||
|
const DRAWDB_PORT = process.env.DRAWDB_PORT || 8080;
|
||||||
|
|
||||||
|
app.use(cors())
|
||||||
|
app.use(express.json())
|
||||||
|
|
||||||
|
// Serve the static files from the DrawDB app
|
||||||
|
app.use(express.static(DRAWDB_HOME));
|
||||||
|
|
||||||
|
app.post('/api/usercode-files/', (req, res) => {
|
||||||
|
const { filename, content } = req.body;
|
||||||
|
|
||||||
|
if (!filename || !content) {
|
||||||
|
return res.status(400).send('Filename and content are required');
|
||||||
|
}
|
||||||
|
const filePath = path.join(DRAWDB_FILE_DIR, filename);
|
||||||
|
|
||||||
|
fs.writeFile(filePath, JSON.stringify(content), 'utf8', (err) => {
|
||||||
|
if (err) {
|
||||||
|
return res.status(500).send('Error writing ddb file');
|
||||||
|
}
|
||||||
|
res.send('File written successfully');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/api/usercode-files/:filename', (req, res) => {
|
||||||
|
const filename = req.params.filename;
|
||||||
|
const filePath = path.join(DRAWDB_FILE_DIR, filename); // Adjust the path based on your directory structure
|
||||||
|
|
||||||
|
fs.readFile(filePath, 'utf8', (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
if (err.code === 'ENOENT') {
|
||||||
|
// File not found
|
||||||
|
return res.status(404).send('File not found');
|
||||||
|
}
|
||||||
|
// Some other error
|
||||||
|
return res.status(500).send('Error reading file');
|
||||||
|
}
|
||||||
|
res.send(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.delete('/api/usercode-files/:filename', (req, res) => {
|
||||||
|
const filename = req.params.filename;
|
||||||
|
|
||||||
|
if (!filename) {
|
||||||
|
return res.status(400).send('Filename is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
const filePath = path.join(DRAWDB_FILE_DIR, filename);
|
||||||
|
|
||||||
|
fs.access(filePath, fs.constants.F_OK, (err) => {
|
||||||
|
if (err) {
|
||||||
|
return res.send('File does not exists.');
|
||||||
|
}
|
||||||
|
fs.unlink(filePath, (err) => {
|
||||||
|
if (err) {
|
||||||
|
return res.status(500).send('Error deleting file');
|
||||||
|
}
|
||||||
|
res.send('File deleted successfully');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
// Handles any requests that don't match the ones above
|
||||||
|
app.get('*', (req, res) => {
|
||||||
|
res.sendFile(path.join(DRAWDB_HOME, 'index.html'));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
app.listen(DRAWDB_PORT, () => {
|
||||||
|
console.log(`DrawDB is running on port ${DRAWDB_PORT}`);
|
||||||
|
});
|
1997
server/package-lock.json
generated
Normal file
1997
server/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
22
server/package.json
Normal file
22
server/package.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "drawdb-wrapper",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "node index.js",
|
||||||
|
"build": "webpack"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"express": "^4.21.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"webpack": "^5.94.0",
|
||||||
|
"webpack-cli": "^5.1.4"
|
||||||
|
}
|
||||||
|
}
|
2
server/server.js
Normal file
2
server/server.js
Normal file
File diff suppressed because one or more lines are too long
256
server/server.js.LICENSE.txt
Normal file
256
server/server.js.LICENSE.txt
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
/*
|
||||||
|
object-assign
|
||||||
|
(c) Sindre Sorhus
|
||||||
|
@license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* accepts
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* body-parser
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* body-parser
|
||||||
|
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* bytes
|
||||||
|
* Copyright(c) 2012-2014 TJ Holowaychuk
|
||||||
|
* Copyright(c) 2015 Jed Watson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* content-disposition
|
||||||
|
* Copyright(c) 2014-2017 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* content-type
|
||||||
|
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* cookie
|
||||||
|
* Copyright(c) 2012-2014 Roman Shtylman
|
||||||
|
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* depd
|
||||||
|
* Copyright(c) 2014-2018 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* destroy
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2015-2022 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* ee-first
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* encodeurl
|
||||||
|
* Copyright(c) 2016 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* escape-html
|
||||||
|
* Copyright(c) 2012-2013 TJ Holowaychuk
|
||||||
|
* Copyright(c) 2015 Andreas Lubbe
|
||||||
|
* Copyright(c) 2015 Tiancheng "Timothy" Gu
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* etag
|
||||||
|
* Copyright(c) 2014-2016 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* express
|
||||||
|
* Copyright(c) 2009-2013 TJ Holowaychuk
|
||||||
|
* Copyright(c) 2013 Roman Shtylman
|
||||||
|
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* express
|
||||||
|
* Copyright(c) 2009-2013 TJ Holowaychuk
|
||||||
|
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* finalhandler
|
||||||
|
* Copyright(c) 2014-2022 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* forwarded
|
||||||
|
* Copyright(c) 2014-2017 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* fresh
|
||||||
|
* Copyright(c) 2012 TJ Holowaychuk
|
||||||
|
* Copyright(c) 2016-2017 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* http-errors
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2016 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* media-typer
|
||||||
|
* Copyright(c) 2014 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* merge-descriptors
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* methods
|
||||||
|
* Copyright(c) 2013-2014 TJ Holowaychuk
|
||||||
|
* Copyright(c) 2015-2016 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* mime-db
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2015-2022 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* mime-types
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* negotiator
|
||||||
|
* Copyright(c) 2012 Federico Romero
|
||||||
|
* Copyright(c) 2012-2014 Isaac Z. Schlueter
|
||||||
|
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* on-finished
|
||||||
|
* Copyright(c) 2013 Jonathan Ong
|
||||||
|
* Copyright(c) 2014 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* parseurl
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2014-2017 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* proxy-addr
|
||||||
|
* Copyright(c) 2014-2016 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* range-parser
|
||||||
|
* Copyright(c) 2012-2014 TJ Holowaychuk
|
||||||
|
* Copyright(c) 2015-2016 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* raw-body
|
||||||
|
* Copyright(c) 2013-2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2014-2022 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* send
|
||||||
|
* Copyright(c) 2012 TJ Holowaychuk
|
||||||
|
* Copyright(c) 2014-2022 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* serve-static
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* Copyright(c) 2014-2016 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* statuses
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2016 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* toidentifier
|
||||||
|
* Copyright(c) 2016 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* type-is
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* unpipe
|
||||||
|
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* vary
|
||||||
|
* Copyright(c) 2014-2017 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
1
server/usercode/Untitled Diagram.ddb
Normal file
1
server/usercode/Untitled Diagram.ddb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"author":"Unnamed","title":"Untitled Diagram","date":"2024-09-20T09:27:33.343Z","tables":[{"id":0,"name":"table_0","x":0,"y":0,"fields":[{"name":"id","type":"INTEGER","default":"","check":"","primary":true,"unique":true,"notNull":true,"increment":true,"comment":"","id":0}],"comment":"","indices":[],"color":"#175e7a","key":1726824435540}],"relationships":[],"notes":[],"subjectAreas":[],"database":"mysql"}
|
12
server/webpack.config.js
Normal file
12
server/webpack.config.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mode: 'production',
|
||||||
|
entry: './index.js',
|
||||||
|
output: {
|
||||||
|
path: path.join(__dirname),
|
||||||
|
publicPath: '/',
|
||||||
|
filename: 'server.js',
|
||||||
|
},
|
||||||
|
target: 'node',
|
||||||
|
};
|
@@ -1,9 +1,11 @@
|
|||||||
import Dexie from "dexie";
|
import Dexie from "dexie";
|
||||||
|
import 'dexie-observable';
|
||||||
import { templateSeeds } from "./seeds";
|
import { templateSeeds } from "./seeds";
|
||||||
|
import { diagramToDrawDbFile } from "../utils/parser"
|
||||||
|
|
||||||
export const db = new Dexie("drawDB");
|
export const db = new Dexie("drawDB");
|
||||||
|
|
||||||
db.version(6).stores({
|
db.version(7).stores({
|
||||||
diagrams: "++id, lastModified, loadedFromGistId",
|
diagrams: "++id, lastModified, loadedFromGistId",
|
||||||
templates: "++id, custom",
|
templates: "++id, custom",
|
||||||
});
|
});
|
||||||
@@ -11,3 +13,41 @@ db.version(6).stores({
|
|||||||
db.on("populate", (transaction) => {
|
db.on("populate", (transaction) => {
|
||||||
transaction.templates.bulkAdd(templateSeeds).catch((e) => console.log(e));
|
transaction.templates.bulkAdd(templateSeeds).catch((e) => console.log(e));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const debounce = (func, delay) => {
|
||||||
|
let timer;
|
||||||
|
return function(...args) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
func.apply(this, args);
|
||||||
|
}, delay);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const debouncedChangesHandler = debounce(async (changes) => {
|
||||||
|
handleDiagramChanges(changes.filter(c => c.table === "diagrams"))
|
||||||
|
}, 1500);
|
||||||
|
|
||||||
|
const handleDiagramChanges = (diagramChanges) => {
|
||||||
|
console.log("diagramChanges", diagramChanges);
|
||||||
|
|
||||||
|
// Handle create / update / delete separately
|
||||||
|
|
||||||
|
// Parse changes to ddb file format
|
||||||
|
const ddbFiles = diagramChanges.map(d => diagramToDrawDbFile(d.obj));
|
||||||
|
|
||||||
|
// Write files to usercode
|
||||||
|
ddbFiles.forEach(ddbFile => {
|
||||||
|
fetch('/api/usercode-files', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ filename: `${ddbFile.title}.ddb`, content: ddbFile })
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
db.on('changes', debouncedChangesHandler)
|
||||||
|
28
src/utils/parser.js
Normal file
28
src/utils/parser.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { databases } from "../data/databases";
|
||||||
|
|
||||||
|
export function diagramToDrawDbFile(diagram) {
|
||||||
|
const {
|
||||||
|
name,
|
||||||
|
lastModified,
|
||||||
|
tables,
|
||||||
|
references,
|
||||||
|
notes,
|
||||||
|
areas,
|
||||||
|
database,
|
||||||
|
types,
|
||||||
|
enums
|
||||||
|
} = diagram;
|
||||||
|
|
||||||
|
return {
|
||||||
|
author: "Unnamed",
|
||||||
|
title: name,
|
||||||
|
date: lastModified.toISOString(),
|
||||||
|
tables: tables,
|
||||||
|
relationships: references,
|
||||||
|
notes: notes,
|
||||||
|
subjectAreas: areas,
|
||||||
|
database: database,
|
||||||
|
...(databases[database].hasTypes && { types: types }),
|
||||||
|
...(databases[database].hasEnums && { enums: enums }),
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user