more stuff

This commit is contained in:
HRG @ SCExC 2024-06-08 11:42:27 -04:00
parent 835c5fdd66
commit d2ad994716
6 changed files with 84 additions and 50 deletions

View file

@ -17,7 +17,7 @@ const PORT = 3000;
let viewpath = path.join(__dirname, "views"); let viewpath = path.join(__dirname, "views");
let eta = new Eta({ views: viewpath, cache: false, autoEscape: true }); let eta = new Eta({ views: viewpath, cache: false, autoEscape: true });
const routes = { GET: [], POST: [], PUT: [], DELETE: [] }; let routes = { GET: [], POST: [], PUT: [], DELETE: [] };
app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static("public")); app.use(express.static("public"));
@ -34,7 +34,7 @@ function getAllRoutes(db) {
SELECT routes.*, structures.route_prefix SELECT routes.*, structures.route_prefix
FROM routes FROM routes
JOIN structures ON routes.structure_id = structures.id JOIN structures ON routes.structure_id = structures.id
ORDER BY routes.id ASC; ORDER BY routes.updated_at DESC;
` `
) )
.all(); .all();
@ -79,16 +79,23 @@ function applyMigrations() {
} }
function buildRoutes() { function buildRoutes() {
let newRoutes = {
GET: [],
POST: [],
PUT: [],
DELETE: [],
};
for (let route of getAllRoutes(db)) { for (let route of getAllRoutes(db)) {
const prefix = route.route_prefix; const prefix = route.route_prefix;
console.log(route);
const p = prefix ? path.join(route.route_prefix, route.path) : route.path; const p = prefix ? path.join(route.route_prefix, route.path) : route.path;
routes[route.verb].push({ newRoutes[route.verb].push({
matcher: match(p, { decode: decodeURIComponent }), matcher: match(p, { decode: decodeURIComponent }),
id: route.id, id: route.id,
path: route.path, path: route.path,
}); });
} }
routes = newRoutes;
} }
applyMigrations(); applyMigrations();
@ -273,10 +280,18 @@ function createTemplate(db, structureId, name, content, testObjectString) {
function getDbsForStructure(db, structureId) { function getDbsForStructure(db, structureId) {
return db return db
.prepare( .prepare(
`SELECT * `SELECT
*,
CASE
WHEN structure_dbs.structure_id != dbs.structure_id THEN 1
ELSE 0
END AS is_aliased,
structure_dbs.structure_id as alias_struct_id,
dbs.structure_id as db_struct_id
FROM structure_dbs FROM structure_dbs
INNER JOIN dbs ON structure_dbs.db_id = dbs.id INNER JOIN dbs ON structure_dbs.db_id = dbs.id
WHERE structure_dbs.structure_id = ?; WHERE structure_dbs.structure_id = ?
ORDER BY structure_dbs.created_at, is_aliased ASC;
` `
) )
.all(structureId); .all(structureId);
@ -399,7 +414,7 @@ function cloneStructure(
newStructureName, newStructureName,
userId, userId,
routePrefix = "", routePrefix = "",
cloneDb = false cloneDbs = []
) { ) {
const transaction = db.transaction(() => { const transaction = db.transaction(() => {
const cloneStructure = db.prepare(` const cloneStructure = db.prepare(`
@ -414,12 +429,22 @@ function cloneStructure(
structId structId
).lastInsertRowid; ).lastInsertRowid;
if (cloneDb) {
const dbIds = db const dbIds = db
.prepare(`select db_id from structure_dbs where structure_id = ?;`) .prepare(`select db_id from structure_dbs where structure_id = ?;`)
.all(structId); .all(structId);
const toClone = new Set(cloneDbs);
const toAlias = new Set();
console.log(toClone, dbIds)
for (let { db_id } of dbIds) { for (let { db_id } of dbIds) {
if (!toClone.has(db_id.toString())) {
toAlias.add(db_id.toString());
}
}
for (let db_id of toClone) {
const newDb = db const newDb = db
.prepare( .prepare(
` `
@ -439,7 +464,6 @@ function cloneStructure(
db.prepare(`select id from dbs where structure_id = ?`) db.prepare(`select id from dbs where structure_id = ?`)
.all(newStructId) .all(newStructId)
.map((new_db) => { .map((new_db) => {
console.log(db_id, new_db.id);
const srcPath = path.join(__dirname, "dbs", `${db_id}.sqlite`); const srcPath = path.join(__dirname, "dbs", `${db_id}.sqlite`);
const destPath = path.join(__dirname, "dbs", `${new_db.id}.sqlite`); const destPath = path.join(__dirname, "dbs", `${new_db.id}.sqlite`);
fs.copyFileSync(srcPath, destPath); fs.copyFileSync(srcPath, destPath);
@ -447,14 +471,15 @@ function cloneStructure(
fs.copyFileSync(srcPath + "-wal", destPath + "-wal"); fs.copyFileSync(srcPath + "-wal", destPath + "-wal");
}); });
} }
} else { for (let db_id of toAlias) {
db.prepare( db.prepare(
` `
INSERT INTO structure_dbs (db_id, structure_id, alias) INSERT INTO structure_dbs (db_id, structure_id, alias)
SELECT db_id, ?, alias FROM structure_dbs WHERE structure_id = ?; SELECT db_id, ?, alias FROM structure_dbs WHERE structure_id = ? AND db_id = ?;
` `
).run(newStructId, structId); ).run(newStructId, structId, db_id);
} }
const cloneTemplates = db.prepare(` const cloneTemplates = db.prepare(`
INSERT INTO templates (name, content, structure_id, test_object, engine) INSERT INTO templates (name, content, structure_id, test_object, engine)
SELECT name, content, ?, test_object, engine FROM templates WHERE structure_id = ?; SELECT name, content, ?, test_object, engine FROM templates WHERE structure_id = ?;
@ -509,7 +534,6 @@ function bootstrapTemplateWithHTMXetc(
$.root().children().attr("data-bliss-route", blissRoute); $.root().children().attr("data-bliss-route", blissRoute);
$.root().children().attr("data-bliss-clone", blissClone); $.root().children().attr("data-bliss-clone", blissClone);
if (blissCopy) $.root().children().attr("data-bliss-copy", blissCopy); if (blissCopy) $.root().children().attr("data-bliss-copy", blissCopy);
console.log(blissCopy, "fleem")
htmlString = $.html(); htmlString = $.html();
} }
@ -560,7 +584,6 @@ app.get("/workshop/:structure_id", (req, res) => {
app.post("/workshop/:structure_id/clone", (req, res) => { app.post("/workshop/:structure_id/clone", (req, res) => {
let routePrefix = req.body.route_prefix; let routePrefix = req.body.route_prefix;
routePrefix = routePrefix[0] == "/" ? routePrefix : "/" + routePrefix; routePrefix = routePrefix[0] == "/" ? routePrefix : "/" + routePrefix;
const cloneDb = req.body.clone_db == "true";
let newStructureId; let newStructureId;
try { try {
newStructureId = cloneStructure( newStructureId = cloneStructure(
@ -569,7 +592,7 @@ app.post("/workshop/:structure_id/clone", (req, res) => {
1, 1,
// req.session.userId, // req.session.userId,
routePrefix, routePrefix,
cloneDb req.body.clone_dbs
); );
buildRoutes(); buildRoutes();
} catch (e) { } catch (e) {
@ -750,14 +773,15 @@ app.get("/workshop/:structure_id/template/:template_id/preview", (req, res) => {
app.get("/workshop/:structure_id/route/:id", (req, res) => { app.get("/workshop/:structure_id/route/:id", (req, res) => {
const route = getRoute(db, req.params.id); const route = getRoute(db, req.params.id);
const routePrefix = getStructure(db, req.params.structure_id).route_prefix; const routePrefix = getStructure(db, req.params.structure_id).route_prefix;
let previewUrl = routePrefix
? path.join(routePrefix || "", route.path)
: route.path;
return res.send( return res.send(
bootstrapTemplateWithHTMXetc( bootstrapTemplateWithHTMXetc(
eta.render("workshop/route", { eta.render("workshop/route", {
route: route, route: route,
previewUrl: previewUrl:
route["verb"] == "GET" route["verb"] == "GET" ? previewUrl : "/workshop/do-something-here",
? path.join(routePrefix, route.path)
: "/workshop/tip",
...sidebarStuff(db, req.params.structure_id), ...sidebarStuff(db, req.params.structure_id),
}) })
) )
@ -879,10 +903,14 @@ app.get("/workshop/:structure_id/new_db_modal", (req, res) => {
app.get("/workshop/:structure_id/clone_modal", (req, res) => { app.get("/workshop/:structure_id/clone_modal", (req, res) => {
const structure = getStructure(db, req.params.structure_id); const structure = getStructure(db, req.params.structure_id);
const dbs = getDbsForStructure(db, req.params.structure_id);
console.log(dbs);
return res.send( return res.send(
bootstrapTemplateWithHTMXetc( bootstrapTemplateWithHTMXetc(
eta.render("workshop/clone_structure_modal", { eta.render("workshop/clone_structure_modal", {
structure, structure,
dbs,
defaultRoutePrefix: path.join(structure.route_prefix || "", "clone"), defaultRoutePrefix: path.join(structure.route_prefix || "", "clone"),
}) })
) )
@ -945,12 +973,13 @@ app.all("*", (req, res) => {
bootstrapTemplateWithHTMXetc( bootstrapTemplateWithHTMXetc(
args[0], args[0],
`/workshop/${route.structure_id}/route/${route.id}`, `/workshop/${route.structure_id}/route/${route.id}`,
`/workshop/${route.structure_id}/clone/`, `/workshop/${route.structure_id}/clone_modal/`,
verb == "GET" ? embedHTML(req.originalUrl) : null verb == "GET" ? embedHTML(req.originalUrl) : null
) )
); );
}; };
res.render = (template, context) => { res.render = (template, context) => {
context = context || {};
context.route = function (url) { context.route = function (url) {
return __urlPrefix ? path.join(__urlPrefix, url) : url; return __urlPrefix ? path.join(__urlPrefix, url) : url;
}; };

View file

@ -63,6 +63,7 @@ CREATE TABLE structure_dbs (
PRIMARY KEY(db_id, structure_id), PRIMARY KEY(db_id, structure_id),
FOREIGN KEY(db_id) REFERENCES dbs(id), FOREIGN KEY(db_id) REFERENCES dbs(id),
FOREIGN KEY(structure_id) REFERENCES structures(id) FOREIGN KEY(structure_id) REFERENCES structures(id)
UNIQUE(alias, structure_id)
); );
CREATE TABLE files ( CREATE TABLE files (

View file

@ -10,10 +10,13 @@
<label class="text-xs">Route Prefix</label> <label class="text-xs">Route Prefix</label>
<input name="route_prefix" id="route_prefix" type="text" value="<%= it.defaultRoutePrefix %>" /> <input name="route_prefix" id="route_prefix" type="text" value="<%= it.defaultRoutePrefix %>" />
</div> </div>
<div class="text-xs">Clone DBs</div>
<% for (let db of it.dbs) { %>
<div class="flex gap-2"> <div class="flex gap-2">
<input id="default-checkbox" type="checkbox" name="cloneDBs" value="true"> <input id="<%= db.id %>" type="checkbox" name="clone_dbs" value="<%= db.id %>" <% if (!db.is_aliased) { %> <%= "checked" %> <% } %>>
<label class="text-xs">Clone DBs</label> <label for="<%= db.id %>" class="text-xs"><%= db.alias %> <% if (db.is_aliased) { %>(aliased)<% } %></label>
</div> </div>
<% } %>
<section class="flex flex-end gap-2" style="justify-content: flex-end"> <section class="flex flex-end gap-2" style="justify-content: flex-end">
<button class="bg-green-500 rounded p-2 hover:bg-green-700 text-white" type="submit">Clone</button> <button class="bg-green-500 rounded p-2 hover:bg-green-700 text-white" type="submit">Clone</button>
<button class="bg-gray-400 rounded p-2 hover:bg-gray-700 text-white" type="button" _="on click trigger closeModal">Cancel</button> <button class="bg-gray-400 rounded p-2 hover:bg-gray-700 text-white" type="button" _="on click trigger closeModal">Cancel</button>

View file

@ -8,9 +8,9 @@
</div> </div>
<div class="window-body"> <div class="window-body">
<form hx-post="/workshop/<%= it.structure.id %>/route" hx-target="#response"> <form hx-post="/workshop/<%= it.structure.id %>/route" hx-target="#response">
<div class="field-row-stacked" style="width: 200px"> <div class="field-row-stacked" style="width: 300px">
<label for="path">Path (e.g. /foo/bar)</label> <label for="path">Path (e.g. /foo/bar)</label>
<input name="path" id="name" type="text" /> <div class="flex items-center"><%= it.structure.route_prefix %>/<input name="path" id="name" type="text" class="flex-grow" /></div>
</div> </div>
<fieldset> <fieldset>
<legend>verb</legend> <legend>verb</legend>

View file

@ -20,7 +20,7 @@
<form hx-put="/workshop/<%= it.structure.id %>/settings" hx-target="#result" class="p-2 flex flex-col gap-2 max-w-48"> <form hx-put="/workshop/<%= it.structure.id %>/settings" hx-target="#result" class="p-2 flex flex-col gap-2 max-w-48">
<div class="field-row-stacked"> <div class="field-row-stacked">
<label for="name">Route Prefix</label> <label for="name">Route Prefix</label>
<input name="route_prefix" value="<%= it.structure.route_prefix %>"> <input name="route_prefix" value="<%= it.structure.route_prefix || "" %>">
</div> </div>
<button id="save-btn" type="submit">Save</button> <button id="save-btn" type="submit">Save</button>
<div id="result"></div> <div id="result"></div>

View file

@ -7,7 +7,7 @@
<li> <li>
<a href="/workshop/<%= it.structure.id %>/route/<%= route.id %>"> <a href="/workshop/<%= it.structure.id %>/route/<%= route.id %>">
<%= route.verb %> - <%= route.verb %> -
<%= it.structure.route_prefix %><%= route.path %> <% if (it.structure.route_prefix) { %><span class="text-gray-500"><%= it.structure.route_prefix %></span><% } %><span class="bold"><%= route.path %></span>
</a> </a>
</li> </li>
<% }) %> <% }) %>
@ -46,6 +46,7 @@
<li class="<% if (it.db?.id == db.id) { %>font-bold text-green-800<% } %>"> <li class="<% if (it.db?.id == db.id) { %>font-bold text-green-800<% } %>">
<a href="/workshop/<%= it.structure.id %>/db/<%= db.id %>"> <a href="/workshop/<%= it.structure.id %>/db/<%= db.id %>">
<%= db.alias %> <%= db.alias %>
<% if (db.is_aliased) { %>(alias)<% } %>
</a> </a>
</li> </li>
<% }) %> <% }) %>