mirror of
https://github.com/morten-olsen/homelab-operator.git
synced 2026-02-08 01:36:28 +01:00
lot more stuff
This commit is contained in:
@@ -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 };
|
||||
|
||||
@@ -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
54
src/utils/queues.ts
Normal 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
12
src/utils/secrets.ts
Normal 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
6
src/utils/types.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type ExpectedAny = any;
|
||||
}
|
||||
|
||||
export {};
|
||||
@@ -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 };
|
||||
Reference in New Issue
Block a user