1import { alchemyLabelKeys } from "../Labels.ts";
2
3export const lastSegment = (value: string) => {
4 const trimmed = value.replace(/\/+$/, "");
5 const parts = trimmed.split("/");
6 return parts[parts.length - 1] || trimmed;
7};
8
9export const encodeDescription = (
10 labels: Record<string, string>,
11 description: string | undefined,
12): string => {
13 const marker = `[alchemy ${alchemyLabelKeys.stack}=${labels[alchemyLabelKeys.stack]} ${alchemyLabelKeys.stage}=${labels[alchemyLabelKeys.stage]} ${alchemyLabelKeys.id}=${labels[alchemyLabelKeys.id]}]`;
14 return description ? `${marker}\n${description}` : marker;
15};
16
17export const parseDescription = (
18 description: string | undefined,
19): {
20 labels: Record<string, string>;
21 description: string | undefined;
22} => {
23 if (!description?.startsWith("[alchemy ")) {
24 return { labels: {}, description };
25 }
26 const end = description.indexOf("]");
27 if (end < 0) return { labels: {}, description };
28 const labels: Record<string, string> = {};
29 for (const part of description.slice("[alchemy ".length, end).split(/\s+/)) {
30 const eq = part.indexOf("=");
31 if (eq > 0) {
32 labels[part.slice(0, eq)] = part.slice(eq + 1);
33 }
34 }
35 const rest = description.slice(end + 1).replace(/^\n/, "");
36 return { labels, description: rest.length > 0 ? rest : undefined };
37};
38
39export const hasOwnershipMarker = (description: string | undefined) =>
40 Object.keys(parseDescription(description).labels).some((key) =>
41 key.startsWith("alchemy-"),
42 );
43
44export const jsonEqual = (left: unknown, right: unknown) =>
45 JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
46
47export const sortedStrings = (values: readonly string[] | undefined) =>
48 [...(values ?? [])].slice().sort();