105 lines
3.2 KiB
TypeScript
105 lines
3.2 KiB
TypeScript
import db from './database';
|
|
|
|
// ── Types ─────────────────────────────────────────────────────────────────────
|
|
|
|
export type ProjectRow = {
|
|
id: number;
|
|
name: string;
|
|
description: string;
|
|
project_json: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
};
|
|
|
|
export type CreateProjectInput = {
|
|
name: string;
|
|
description?: string;
|
|
project_json?: string;
|
|
};
|
|
|
|
export type UpdateProjectInput = {
|
|
name?: string;
|
|
description?: string;
|
|
project_json?: string;
|
|
};
|
|
|
|
// Minimal valid project definition created when none is supplied on POST
|
|
const DEFAULT_PROJECT_JSON = JSON.stringify({
|
|
schemaVersion: '0.1.0',
|
|
project: {
|
|
name: '',
|
|
pages: [],
|
|
actions: [],
|
|
variables: {},
|
|
settings: {},
|
|
},
|
|
});
|
|
|
|
// ── Queries ───────────────────────────────────────────────────────────────────
|
|
|
|
const stmtList = db.prepare<[], ProjectRow>(`
|
|
SELECT id, name, description, project_json, created_at, updated_at
|
|
FROM projects
|
|
ORDER BY created_at DESC
|
|
`);
|
|
|
|
const stmtGetById = db.prepare<[number], ProjectRow>(`
|
|
SELECT id, name, description, project_json, created_at, updated_at
|
|
FROM projects
|
|
WHERE id = ?
|
|
`);
|
|
|
|
const stmtInsert = db.prepare<[string, string, string], { lastInsertRowid: number }>(`
|
|
INSERT INTO projects (name, description, project_json)
|
|
VALUES (?, ?, ?)
|
|
`);
|
|
|
|
const stmtUpdate = db.prepare<[string, string, string, number], void>(`
|
|
UPDATE projects
|
|
SET name = ?, description = ?, project_json = ?,
|
|
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
WHERE id = ?
|
|
`);
|
|
|
|
const stmtDelete = db.prepare<[number], void>(`
|
|
DELETE FROM projects WHERE id = ?
|
|
`);
|
|
|
|
// ── Data access functions ─────────────────────────────────────────────────────
|
|
|
|
export function listProjects(): ProjectRow[] {
|
|
return stmtList.all();
|
|
}
|
|
|
|
export function getProjectById(id: number): ProjectRow | undefined {
|
|
return stmtGetById.get(id);
|
|
}
|
|
|
|
export function createProject(input: CreateProjectInput): ProjectRow {
|
|
const { name, description = '', project_json = DEFAULT_PROJECT_JSON } = input;
|
|
// Embed the project name into the default JSON so it is consistent
|
|
const json =
|
|
project_json === DEFAULT_PROJECT_JSON
|
|
? JSON.stringify({ ...JSON.parse(DEFAULT_PROJECT_JSON), project: { ...JSON.parse(DEFAULT_PROJECT_JSON).project, name } })
|
|
: project_json;
|
|
const result = stmtInsert.run(name, description, json);
|
|
return getProjectById(result.lastInsertRowid as number) as ProjectRow;
|
|
}
|
|
|
|
export function updateProject(id: number, input: UpdateProjectInput): ProjectRow | undefined {
|
|
const existing = getProjectById(id);
|
|
if (!existing) return undefined;
|
|
stmtUpdate.run(
|
|
input.name ?? existing.name,
|
|
input.description ?? existing.description,
|
|
input.project_json ?? existing.project_json,
|
|
id,
|
|
);
|
|
return getProjectById(id);
|
|
}
|
|
|
|
export function deleteProject(id: number): boolean {
|
|
const result = stmtDelete.run(id);
|
|
return result.changes > 0;
|
|
}
|