lot more stuff

This commit is contained in:
Morten Olsen
2025-08-04 23:44:14 +02:00
parent daf0ea21bb
commit 757b2fcfac
185 changed files with 115899 additions and 1874 deletions

View File

@@ -1,5 +1,5 @@
const GROUP = 'homelab.mortenolsen.pro';
const NAMESPACE = 'homelab';
const API_VERSION = `${GROUP}/v1`;
const FIELDS = {
domain: {
@@ -7,4 +7,10 @@ const FIELDS = {
},
};
export { GROUP, NAMESPACE, FIELDS };
const CONTROLLED_LABEL = {
[`${GROUP}/controlled`]: 'true',
};
const CONTROLLED_LABEL_SELECTOR = `${GROUP}/controlled=true`;
export { GROUP, FIELDS, CONTROLLED_LABEL, CONTROLLED_LABEL_SELECTOR, API_VERSION };

View File

@@ -1,4 +1,4 @@
const getWithNamespace = (input: string) => {
const getWithNamespace = (input: string, defaultNamespace?: string) => {
const result = input.split('/');
const first = result.pop();
if (!first) {
@@ -6,7 +6,7 @@ const getWithNamespace = (input: string) => {
}
return {
name: first,
namespace: result.join('/'),
namespace: result.length > 0 ? result.join('/') : defaultNamespace,
};
};

54
src/utils/queues.ts Normal file
View File

@@ -0,0 +1,54 @@
type CoalescingQueuedOptions<T> = {
action: () => Promise<T>;
};
const createResolvable = <T>() => {
let resolve: (item: T) => void = () => {};
let reject: (item: T) => void = () => {};
const promise = new Promise<T>((res, rej) => {
resolve = res;
reject = rej;
});
return { resolve, reject, promise };
};
type Resolveable<T> = ReturnType<typeof createResolvable<T>>;
class CoalescingQueued<T> {
#options: CoalescingQueuedOptions<T>;
#next?: Resolveable<T>;
#current?: Promise<T>;
constructor(options: CoalescingQueuedOptions<T>) {
this.#options = options;
}
#start = () => {
if (this.#current) {
return;
}
const next = this.#next;
if (next) {
const action = this.#options.action();
this.#current = action;
this.#next = undefined;
action.then(next.resolve);
action.catch(next.reject);
action.finally(() => {
this.#current = undefined;
this.#start();
});
}
};
public run = async () => {
if (!this.#next) {
this.#next = createResolvable<T>();
}
const next = this.#next;
this.#start();
return next.promise;
};
}
export { CoalescingQueued };

12
src/utils/secrets.ts Normal file
View File

@@ -0,0 +1,12 @@
const decodeSecret = <T extends Record<string, string>>(
data: Record<string, ExpectedAny> | undefined,
): T | undefined => {
if (!data) {
return undefined;
}
return Object.fromEntries(
Object.entries(data).map(([name, value]) => [name, Buffer.from(value, 'base64').toString('utf8')]),
) as T;
};
export { decodeSecret };

6
src/utils/types.d.ts vendored Normal file
View File

@@ -0,0 +1,6 @@
declare global {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type ExpectedAny = any;
}
export {};

View File

@@ -1,12 +0,0 @@
declare global {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type ExpectedAny = any;
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
const noop = () => {};
// eslint-disable-next-line @typescript-eslint/no-empty-function
const noopAsync = async () => {};
export { noop, noopAsync };