server: add account creation and login

GitLab: #10
Change-Id: Iddd7ecee7210bc7b839cb2cec5d4291ac725d104
diff --git a/server/src/utils.ts b/server/src/utils.ts
new file mode 100644
index 0000000..4f0b027
--- /dev/null
+++ b/server/src/utils.ts
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 Savoir-faire Linux Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+import { createRequire } from 'node:module';
+
+export function* itRange(lo: number, hi: number) {
+  for (let i = lo; i < hi; ++i) {
+    yield i;
+  }
+}
+
+export function* itMap<T, U>(it: Iterable<T>, cb: (value: T, index: number) => U) {
+  let i = 0;
+  for (const item of it) {
+    yield cb(item, i++);
+  }
+}
+
+export function* itFilter<T>(it: Iterable<T>, cb: (value: T, index: number) => boolean) {
+  let i = 0;
+  for (const item of it) {
+    if (cb(item, i++)) {
+      yield item;
+    }
+  }
+}
+
+export const itToArr = <T>(it: Iterable<T>) => Array.from(it);
+
+export const itToMap = <T, U>(it: Iterable<[T, U]>) => {
+  const m = new Map<T, U>();
+  for (const [k, v] of it) {
+    m.set(k, v);
+  }
+  return m;
+};
+
+export const require = createRequire(import.meta.url);