68 lines
2.3 KiB
TypeScript
68 lines
2.3 KiB
TypeScript
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
import { dirname, join } from 'node:path';
|
|
import {
|
|
validateProjectTemplateSnapshot,
|
|
type ProjectTemplateSnapshot,
|
|
} from '../../shared/project-template';
|
|
|
|
export const PROJECT_TEMPLATE_SNAPSHOT_PATH = '.niancode/project-template.json';
|
|
|
|
export type ProjectTemplateSnapshotReadResult =
|
|
| { status: 'missing' }
|
|
| { status: 'valid'; snapshot: ProjectTemplateSnapshot }
|
|
| { status: 'invalid'; error: string };
|
|
|
|
export function getProjectTemplateSnapshotPath(projectPath: string): string {
|
|
return join(projectPath, '.niancode', 'project-template.json');
|
|
}
|
|
|
|
export async function readProjectTemplateSnapshot(projectPath: string): Promise<ProjectTemplateSnapshotReadResult> {
|
|
const snapshotPath = getProjectTemplateSnapshotPath(projectPath);
|
|
let raw: string;
|
|
try {
|
|
raw = await readFile(snapshotPath, 'utf8');
|
|
} catch (error) {
|
|
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
return { status: 'missing' };
|
|
}
|
|
return { status: 'invalid', error: `${PROJECT_TEMPLATE_SNAPSHOT_PATH}: ${String(error)}` };
|
|
}
|
|
|
|
let parsed: unknown;
|
|
try {
|
|
parsed = JSON.parse(raw);
|
|
} catch (error) {
|
|
return { status: 'invalid', error: `${PROJECT_TEMPLATE_SNAPSHOT_PATH}: invalid JSON (${String(error)})` };
|
|
}
|
|
|
|
const validation = validateProjectTemplateSnapshot(parsed);
|
|
if (!validation.ok) {
|
|
return { status: 'invalid', error: `${PROJECT_TEMPLATE_SNAPSHOT_PATH}: ${validation.error}` };
|
|
}
|
|
return { status: 'valid', snapshot: validation.snapshot };
|
|
}
|
|
|
|
export async function writeProjectTemplateSnapshot(
|
|
projectPath: string,
|
|
snapshot: ProjectTemplateSnapshot,
|
|
): Promise<ProjectTemplateSnapshot> {
|
|
const validation = validateProjectTemplateSnapshot(snapshot);
|
|
if (!validation.ok) {
|
|
throw new Error(validation.error);
|
|
}
|
|
const snapshotPath = getProjectTemplateSnapshotPath(projectPath);
|
|
await mkdir(dirname(snapshotPath), { recursive: true });
|
|
try {
|
|
await writeFile(snapshotPath, `${JSON.stringify(validation.snapshot, null, 2)}\n`, {
|
|
encoding: 'utf8',
|
|
flag: 'wx',
|
|
});
|
|
} catch (error) {
|
|
if ((error as NodeJS.ErrnoException).code === 'EEXIST') {
|
|
throw new Error(`${PROJECT_TEMPLATE_SNAPSHOT_PATH} already exists and cannot be replaced`, { cause: error });
|
|
}
|
|
throw error;
|
|
}
|
|
return validation.snapshot;
|
|
}
|