Initial commit — wiring diagram maker with full feature set
- FastAPI + SQLite backend with routers for diagrams, devices, wires, bundles, connectors, export, and Octopart/Nexar search - Konva.js canvas: ortho/direct/curved routing, wire crossings, harness mode, snap-to-grid, multi-select, drag, resize, undo - Wire features: color/stripe, twisted pair helix, shielded glow, gauge size label, multi-core bundle grouping, length/unit tracking - Device library: connector, terminal block, cable, splice, label, group, relay, fuse, switch, component with custom connector support - Exports: BOM CSV, assembly TXT, JSON, formboard layout, PNG image - Auto-migration for schema changes via ALTER TABLE at startup Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
const API_BASE = "/api";
|
||||
|
||||
async function apiFetch(path, options = {}) {
|
||||
const res = await fetch(`${API_BASE}${path}`, options);
|
||||
if (!res.ok) {
|
||||
const text = await res.text();
|
||||
throw new Error(`API ${res.status}: ${text}`);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
const api = {
|
||||
diagrams: {
|
||||
list: () => apiFetch("/diagrams/"),
|
||||
create: (data) => apiFetch("/diagrams/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
get: (id) => apiFetch(`/diagrams/${id}`),
|
||||
update: (id, data) => apiFetch(`/diagrams/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
delete: (id) => apiFetch(`/diagrams/${id}`, { method: "DELETE" }),
|
||||
},
|
||||
devices: {
|
||||
create: (data) => apiFetch("/devices/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
update: (id, data) => apiFetch(`/devices/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
delete: (id) => apiFetch(`/devices/${id}`, { method: "DELETE" }),
|
||||
},
|
||||
wires: {
|
||||
create: (data) => apiFetch("/wires/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
update: (id, data) => apiFetch(`/wires/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
delete: (id) => apiFetch(`/wires/${id}`, { method: "DELETE" }),
|
||||
},
|
||||
bundles: {
|
||||
listForDiagram: (diagramId) => apiFetch(`/bundles/diagram/${diagramId}`),
|
||||
create: (data) => apiFetch("/bundles/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
update: (id, data) => apiFetch(`/bundles/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
delete: (id) => apiFetch(`/bundles/${id}`, { method: "DELETE" }),
|
||||
},
|
||||
connectors: {
|
||||
list: () => apiFetch("/connectors/"),
|
||||
create: (data) => apiFetch("/connectors/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
update: (id, data) => apiFetch(`/connectors/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
delete: (id) => apiFetch(`/connectors/${id}`, { method: "DELETE" }),
|
||||
},
|
||||
octopart: {
|
||||
status: () => apiFetch("/octopart/status"),
|
||||
search: (q, n) => apiFetch(`/octopart/search?q=${encodeURIComponent(q)}&limit=${n || 8}`),
|
||||
},
|
||||
export: {
|
||||
bomUrl: (id) => `${API_BASE}/export/${id}/bom/csv`,
|
||||
assemblyUrl: (id) => `${API_BASE}/export/${id}/assembly/txt`,
|
||||
jsonUrl: (id) => `${API_BASE}/export/${id}/json`,
|
||||
formboardUrl: (id) => `${API_BASE}/export/${id}/formboard`,
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user