1import { createPhysicalName } from "../../PhysicalName.ts";
2import * as Effect from "effect/Effect";
3
4export const lastSegment = (value: string) => {
5 const trimmed = value.replace(/\/+$/, "");
6 const parts = trimmed.split("/");
7 return parts[parts.length - 1] || trimmed;
8};
9
10export const organizationOf = (
11 explicit: string | undefined,
12 existing: string | undefined,
13 project: string,
14) => explicit ?? existing ?? project;
15
16export const orgParent = (organization: string) =>
17 `organizations/${organization}`;
18
19export const organizationFromName = (name: string | undefined) => {
20 if (name === undefined) return undefined;
21 const match = name.match(/^organizations\/([^/]+)/);
22 return match?.[1];
23};
24
25export const toResourceId = (
26 id: string,
27 explicit: string | undefined,
28 existing: string | undefined,
29 maxLength: number,
30) =>
31 Effect.gen(function* () {
32 if (explicit !== undefined) return explicit;
33 if (existing !== undefined) return existing;
34 let generated = yield* createPhysicalName({
35 id,
36 maxLength,
37 lowercase: true,
38 });
39 if (!/^[a-z]/.test(generated)) {
40 generated = `a${generated}`.slice(0, maxLength);
41 }
42 generated = generated.replace(/-+$/g, "");
43 if (generated.length < 2) {
44 generated = `${generated}x`.slice(0, maxLength);
45 }
46 return generated;
47 });
48
49export const sameJson = (left: unknown, right: unknown) =>
50 JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
51
52export const sameStringList = (
53 left: readonly string[] | undefined,
54 right: readonly string[] | undefined,
55) =>
56 JSON.stringify([...(left ?? [])].sort()) ===
57 JSON.stringify([...(right ?? [])].sort());