more stuff
This commit is contained in:
parent
835c5fdd66
commit
d2ad994716
6 changed files with 84 additions and 50 deletions
67
index.js
67
index.js
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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 (
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
<% }) %>
|
<% }) %>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue