feat: add tags workflow
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import * as yaml from "js-yaml";
|
||||
import { err, ok, Result } from "neverthrow";
|
||||
import { appError, AppError, AppErrorVariant } from "@/error";
|
||||
import {
|
||||
EMPTY_PROJECT_CONFIG,
|
||||
normalizeTag,
|
||||
type ProjectConfig,
|
||||
} from "@/model/projectConfig";
|
||||
|
||||
/**
|
||||
* Parse task-folder config.yml content.
|
||||
* Accepts missing/empty tags → [].
|
||||
*/
|
||||
export function parseProjectConfig(
|
||||
content: string,
|
||||
): Result<ProjectConfig, AppError> {
|
||||
if (content.trim() === "") {
|
||||
return ok({ ...EMPTY_PROJECT_CONFIG });
|
||||
}
|
||||
|
||||
let data: unknown;
|
||||
try {
|
||||
data = yaml.load(content);
|
||||
} catch (error) {
|
||||
const detail = error instanceof Error ? error.message : "invalid YAML";
|
||||
return err(
|
||||
appError(AppErrorVariant.INVALID_PROJECT_CONFIG, { detail }),
|
||||
);
|
||||
}
|
||||
|
||||
if (data === null || data === undefined) {
|
||||
return ok({ ...EMPTY_PROJECT_CONFIG });
|
||||
}
|
||||
|
||||
if (typeof data !== "object" || Array.isArray(data)) {
|
||||
return err(
|
||||
appError(AppErrorVariant.INVALID_PROJECT_CONFIG, {
|
||||
detail: "root must be a mapping",
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const record = data as Record<string, unknown>;
|
||||
if (record.tags === undefined) {
|
||||
return ok({ tags: [] });
|
||||
}
|
||||
|
||||
if (!Array.isArray(record.tags)) {
|
||||
return err(
|
||||
appError(AppErrorVariant.INVALID_PROJECT_CONFIG, {
|
||||
detail: "tags must be an array of strings",
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const tags: string[] = [];
|
||||
const seen = new Set<string>();
|
||||
for (const item of record.tags) {
|
||||
if (typeof item !== "string") {
|
||||
return err(
|
||||
appError(AppErrorVariant.INVALID_PROJECT_CONFIG, {
|
||||
detail: "tags must be an array of strings",
|
||||
}),
|
||||
);
|
||||
}
|
||||
const tag = normalizeTag(item);
|
||||
if (!tag || seen.has(tag)) continue;
|
||||
seen.add(tag);
|
||||
tags.push(tag);
|
||||
}
|
||||
|
||||
return ok({ tags });
|
||||
}
|
||||
Reference in New Issue
Block a user