This is an automated email from the ASF dual-hosted git repository.
sciabarracom pushed a commit to branch 0.9.0
in repository https://gitbox.apache.org/repos/asf/openserverless-task.git
The following commit(s) were added to refs/heads/0.9.0 by this push:
new dcaf9d8 removing configurator
dcaf9d8 is described below
commit dcaf9d88ee49e098d9aa4212121f03847cb21504
Author: Michele Sciabarra <[email protected]>
AuthorDate: Mon Sep 28 21:06:07 2026 +0100
removing configurator
---
util/config/README.md | 58 --
util/config/configurator.js | 925 ---------------------
util/config/configurator/bun.lock | 41 -
util/config/configurator/configurator.ts | 389 ---------
util/config/configurator/index.ts | 22 -
util/config/configurator/package.json | 19 -
util/config/configurator/tests/fixtures/bad.json | 1 -
.../configurator/tests/fixtures/multi-keys.json | 22 -
.../configurator/tests/fixtures/not-json.txt | 16 -
util/config/configurator/tests/fixtures/valid.json | 11 -
.../configurator/tests/fixtures/with-defaults.json | 26 -
util/config/configurator/tests/index.test.ts | 144 ----
util/config/configurator/tsconfig.json | 27 -
13 files changed, 1701 deletions(-)
diff --git a/util/config/README.md b/util/config/README.md
deleted file mode 100644
index d1e3c35..0000000
--- a/util/config/README.md
+++ /dev/null
@@ -1,58 +0,0 @@
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you under the Apache License, Version 2.0 (the
- ~ "License"); you may not use this file except in compliance
- ~ with the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing,
- ~ software distributed under the License is distributed on an
- ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- ~ KIND, either express or implied. See the License for the
- ~ specific language governing permissions and limitations
- ~ under the License.
--->
-
-## Openserverless Configurator task
-
-### Development:
-
-The configurator is inside the `configurator` folder.
-The entrypoint is the `configurator/index.ts` file. It simply calls the
configurator main function.
-
-All the logic is inside the `configurator/configurator.ts` file. Of course,
you can add more files
-and change the structure as you see fit.
-
-Inside the `configurator` folder, first install dependencies:
-
-```bash
-bun install
-```
-
-In the `package.json` file there are a couple of scripts. The `start` script
will run the configurator:
-
-```bash
-bun run start
-```
-
-### Tests:
-
-There are unit tests inside the `configurator/test` folder. You can run them
with the following command:
-
-```bash
-bun run test
-```
-
-### Building:
-
-To build the configurator and generate the `configurator.js` file, run the
following command:
-
-```bash
-bun run build
-```
-
-It will generate the `configurator.js` file and move it in the parent, where
it can be used by the opsfile task.
diff --git a/util/config/configurator.js b/util/config/configurator.js
deleted file mode 100644
index e8ca22f..0000000
--- a/util/config/configurator.js
+++ /dev/null
@@ -1,925 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// @bun
-var __create = Object.create;
-var __getProtoOf = Object.getPrototypeOf;
-var __defProp = Object.defineProperty;
-var __getOwnPropNames = Object.getOwnPropertyNames;
-var __hasOwnProp = Object.prototype.hasOwnProperty;
-var __toESM = (mod, isNodeMode, target) => {
- target = mod != null ? __create(__getProtoOf(mod)) : {};
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target,
"default", { value: mod, enumerable: true }) : target;
- for (let key of __getOwnPropNames(mod))
- if (!__hasOwnProp.call(to, key))
- __defProp(to, key, {
- get: () => mod[key],
- enumerable: true
- });
- return to;
-};
-var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {}
}).exports, mod), mod.exports);
-
-// node_modules/sisteransi/src/index.js
-var require_src = __commonJS((exports, module) => {
- var ESC = "\x1B";
- var CSI = `${ESC}[`;
- var beep = "\x07";
- var cursor = {
- to(x, y) {
- if (!y)
- return `${CSI}${x + 1}G`;
- return `${CSI}${y + 1};${x + 1}H`;
- },
- move(x, y) {
- let ret = "";
- if (x < 0)
- ret += `${CSI}${-x}D`;
- else if (x > 0)
- ret += `${CSI}${x}C`;
- if (y < 0)
- ret += `${CSI}${-y}A`;
- else if (y > 0)
- ret += `${CSI}${y}B`;
- return ret;
- },
- up: (count = 1) => `${CSI}${count}A`,
- down: (count = 1) => `${CSI}${count}B`,
- forward: (count = 1) => `${CSI}${count}C`,
- backward: (count = 1) => `${CSI}${count}D`,
- nextLine: (count = 1) => `${CSI}E`.repeat(count),
- prevLine: (count = 1) => `${CSI}F`.repeat(count),
- left: `${CSI}G`,
- hide: `${CSI}?25l`,
- show: `${CSI}?25h`,
- save: `${ESC}7`,
- restore: `${ESC}8`
- };
- var scroll = {
- up: (count = 1) => `${CSI}S`.repeat(count),
- down: (count = 1) => `${CSI}T`.repeat(count)
- };
- var erase = {
- screen: `${CSI}2J`,
- up: (count = 1) => `${CSI}1J`.repeat(count),
- down: (count = 1) => `${CSI}J`.repeat(count),
- line: `${CSI}2K`,
- lineEnd: `${CSI}K`,
- lineStart: `${CSI}1K`,
- lines(count) {
- let clear = "";
- for (let i = 0;i < count; i++)
- clear += this.line + (i < count - 1 ? cursor.up() : "");
- if (count)
- clear += cursor.left;
- return clear;
- }
- };
- module.exports = { cursor, scroll, erase, beep };
-});
-
-// node_modules/picocolors/picocolors.js
-var require_picocolors = __commonJS((exports, module) => {
- var argv = process.argv || [];
- var env = process.env;
- var isColorSupported = !(("NO_COLOR" in env) || argv.includes("--no-color"))
&& (("FORCE_COLOR" in env) || argv.includes("--color") || process.platform ===
"win32" || import.meta.require != null && import.meta.require("tty").isatty(1)
&& env.TERM !== "dumb" || ("CI" in env));
- var formatter = (open, close, replace = open) => (input) => {
- let string = "" + input;
- let index = string.indexOf(close, open.length);
- return ~index ? open + replaceClose(string, close, replace, index) + close
: open + string + close;
- };
- var replaceClose = (string, close, replace, index) => {
- let result = "";
- let cursor = 0;
- do {
- result += string.substring(cursor, index) + replace;
- cursor = index + close.length;
- index = string.indexOf(close, cursor);
- } while (~index);
- return result + string.substring(cursor);
- };
- var createColors = (enabled = isColorSupported) => {
- let init = enabled ? formatter : () => String;
- return {
- isColorSupported: enabled,
- reset: init("\x1B[0m", "\x1B[0m"),
- bold: init("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
- dim: init("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
- italic: init("\x1B[3m", "\x1B[23m"),
- underline: init("\x1B[4m", "\x1B[24m"),
- inverse: init("\x1B[7m", "\x1B[27m"),
- hidden: init("\x1B[8m", "\x1B[28m"),
- strikethrough: init("\x1B[9m", "\x1B[29m"),
- black: init("\x1B[30m", "\x1B[39m"),
- red: init("\x1B[31m", "\x1B[39m"),
- green: init("\x1B[32m", "\x1B[39m"),
- yellow: init("\x1B[33m", "\x1B[39m"),
- blue: init("\x1B[34m", "\x1B[39m"),
- magenta: init("\x1B[35m", "\x1B[39m"),
- cyan: init("\x1B[36m", "\x1B[39m"),
- white: init("\x1B[37m", "\x1B[39m"),
- gray: init("\x1B[90m", "\x1B[39m"),
- bgBlack: init("\x1B[40m", "\x1B[49m"),
- bgRed: init("\x1B[41m", "\x1B[49m"),
- bgGreen: init("\x1B[42m", "\x1B[49m"),
- bgYellow: init("\x1B[43m", "\x1B[49m"),
- bgBlue: init("\x1B[44m", "\x1B[49m"),
- bgMagenta: init("\x1B[45m", "\x1B[49m"),
- bgCyan: init("\x1B[46m", "\x1B[49m"),
- bgWhite: init("\x1B[47m", "\x1B[49m")
- };
- };
- module.exports = createColors();
- module.exports.createColors = createColors;
-});
-
-// configurator.ts
-var {$: $2 } = globalThis.Bun;
-
-// node_modules/@clack/core/dist/index.mjs
-var import_sisteransi = __toESM(require_src(), 1);
-import {stdin as $, stdout as k} from "process";
-var import_picocolors = __toESM(require_picocolors(), 1);
-import _ from "readline";
-import {WriteStream as U} from "tty";
-function q({ onlyFirst: t = false } = {}) {
- const u =
["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");
- return new RegExp(u, t ? undefined : "g");
-}
-function S(t) {
- if (typeof t != "string")
- throw new TypeError(`Expected a \`string\`, got \`${typeof t}\``);
- return t.replace(q(), "");
-}
-function j(t) {
- return t && t.__esModule && Object.prototype.hasOwnProperty.call(t,
"default") ? t.default : t;
-}
-function A(t, u = {}) {
- if (typeof t != "string" || t.length === 0 || (u = { ambiguousIsNarrow:
true, ...u }, t = S(t), t.length === 0))
- return 0;
- t = t.replace(DD(), " ");
- const F = u.ambiguousIsNarrow ? 1 : 2;
- let e = 0;
- for (const s of t) {
- const C = s.codePointAt(0);
- if (C <= 31 || C >= 127 && C <= 159 || C >= 768 && C <= 879)
- continue;
- switch (Q.eastAsianWidth(s)) {
- case "F":
- case "W":
- e += 2;
- break;
- case "A":
- e += F;
- break;
- default:
- e += 1;
- }
- }
- return e;
-}
-function tD() {
- const t = new Map;
- for (const [u, F] of Object.entries(r)) {
- for (const [e, s] of Object.entries(F))
- r[e] = { open: `\x1B[${s[0]}m`, close: `\x1B[${s[1]}m` }, F[e] = r[e],
t.set(s[0], s[1]);
- Object.defineProperty(r, u, { value: F, enumerable: false });
- }
- return Object.defineProperty(r, "codes", { value: t, enumerable: false }),
r.color.close = "\x1B[39m", r.bgColor.close = "\x1B[49m", r.color.ansi = T(),
r.color.ansi256 = P(), r.color.ansi16m = W(), r.bgColor.ansi = T(m),
r.bgColor.ansi256 = P(m), r.bgColor.ansi16m = W(m), Object.defineProperties(r,
{ rgbToAnsi256: { value: (u, F, e) => u === F && F === e ? u < 8 ? 16 : u > 248
? 231 : Math.round((u - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(u / 255 *
5) + 6 * Math.round(F / 255 * 5 [...]
- const F = /[a-f\d]{6}|[a-f\d]{3}/i.exec(u.toString(16));
- if (!F)
- return [0, 0, 0];
- let [e] = F;
- e.length === 3 && (e = [...e].map((C) => C + C).join(""));
- const s = Number.parseInt(e, 16);
- return [s >> 16 & 255, s >> 8 & 255, s & 255];
- }, enumerable: false }, hexToAnsi256: { value: (u) =>
r.rgbToAnsi256(...r.hexToRgb(u)), enumerable: false }, ansi256ToAnsi: { value:
(u) => {
- if (u < 8)
- return 30 + u;
- if (u < 16)
- return 90 + (u - 8);
- let F, e, s;
- if (u >= 232)
- F = ((u - 232) * 10 + 8) / 255, e = F, s = F;
- else {
- u -= 16;
- const i = u % 36;
- F = Math.floor(u / 36) / 5, e = Math.floor(i / 6) / 5, s = i % 6 / 5;
- }
- const C = Math.max(F, e, s) * 2;
- if (C === 0)
- return 30;
- let D = 30 + (Math.round(s) << 2 | Math.round(e) << 1 | Math.round(F));
- return C === 2 && (D += 60), D;
- }, enumerable: false }, rgbToAnsi: { value: (u, F, e) =>
r.ansi256ToAnsi(r.rgbToAnsi256(u, F, e)), enumerable: false }, hexToAnsi: {
value: (u) => r.ansi256ToAnsi(r.hexToAnsi256(u)), enumerable: false } }), r;
-}
-function R(t, u, F) {
- return String(t).normalize().replace(/\r\n/g, `
-`).split(`
-`).map((e) => ED(e, u, F)).join(`
-`);
-}
-function aD(t, u) {
- if (t === u)
- return;
- const F = t.split(`
-`), e = u.split(`
-`), s = [];
- for (let C = 0;C < Math.max(F.length, e.length); C++)
- F[C] !== e[C] && s.push(C);
- return s;
-}
-function hD(t) {
- return t === V;
-}
-function v(t, u) {
- t.isTTY && t.setRawMode(u);
-}
-var M = { exports: {} };
-(function(t) {
- var u = {};
- t.exports = u, u.eastAsianWidth = function(e) {
- var s = e.charCodeAt(0), C = e.length == 2 ? e.charCodeAt(1) : 0, D = s;
- return 55296 <= s && s <= 56319 && 56320 <= C && C <= 57343 && (s &= 1023,
C &= 1023, D = s << 10 | C, D += 65536), D == 12288 || 65281 <= D && D <= 65376
|| 65504 <= D && D <= 65510 ? "F" : D == 8361 || 65377 <= D && D <= 65470 ||
65474 <= D && D <= 65479 || 65482 <= D && D <= 65487 || 65490 <= D && D <=
65495 || 65498 <= D && D <= 65500 || 65512 <= D && D <= 65518 ? "H" : 4352 <= D
&& D <= 4447 || 4515 <= D && D <= 4519 || 4602 <= D && D <= 4607 || 9001 <= D
&& D <= 9002 || 11904 < [...]
- }, u.characterLength = function(e) {
- var s = this.eastAsianWidth(e);
- return s == "F" || s == "W" || s == "A" ? 2 : 1;
- };
- function F(e) {
- return e.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
- }
- u.length = function(e) {
- for (var s = F(e), C = 0, D = 0;D < s.length; D++)
- C = C + this.characterLength(s[D]);
- return C;
- }, u.slice = function(e, s, C) {
- textLen = u.length(e), s = s || 0, C = C || 1, s < 0 && (s = textLen + s),
C < 0 && (C = textLen + C);
- for (var D = "", i = 0, n = F(e), E = 0;E < n.length; E++) {
- var h = n[E], o = u.length(h);
- if (i >= s - (o == 2 ? 1 : 0))
- if (i + o <= C)
- D += h;
- else
- break;
- i += o;
- }
- return D;
- };
-})(M);
-var J = M.exports;
-var Q = j(J);
-var X = function() {
- return
/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u20
[...]
-};
-var DD = j(X);
-var m = 10;
-var T = (t = 0) => (u) => `\x1B[${u + t}m`;
-var P = (t = 0) => (u) => `\x1B[${38 + t};5;${u}m`;
-var W = (t = 0) => (u, F, e) => `\x1B[${38 + t};2;${u};${F};${e}m`;
-var r = { modifier: { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3,
23], underline: [4, 24], overline: [53, 55], inverse: [7, 27], hidden: [8, 28],
strikethrough: [9, 29] }, color: { black: [30, 39], red: [31, 39], green: [32,
39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39],
white: [37, 39], blackBright: [90, 39], gray: [90, 39], grey: [90, 39],
redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright:
[94, 39], magentaBright: [95, [...]
-Object.keys(r.modifier);
-var uD = Object.keys(r.color);
-var FD = Object.keys(r.bgColor);
-[...uD];
-var eD = tD();
-var g = new Set(["\x1B", "\x9B"]);
-var sD = 39;
-var b = "\x07";
-var O = "[";
-var CD = "]";
-var I = "m";
-var w = `${CD}8;;`;
-var N = (t) => `${g.values().next().value}${O}${t}${I}`;
-var L = (t) => `${g.values().next().value}${w}${t}${b}`;
-var iD = (t) => t.split(" ").map((u) => A(u));
-var y = (t, u, F) => {
- const e = [...u];
- let s = false, C = false, D = A(S(t[t.length - 1]));
- for (const [i, n] of e.entries()) {
- const E = A(n);
- if (D + E <= F ? t[t.length - 1] += n : (t.push(n), D = 0), g.has(n) && (s
= true, C = e.slice(i + 1).join("").startsWith(w)), s) {
- C ? n === b && (s = false, C = false) : n === I && (s = false);
- continue;
- }
- D += E, D === F && i < e.length - 1 && (t.push(""), D = 0);
- }
- !D && t[t.length - 1].length > 0 && t.length > 1 && (t[t.length - 2] +=
t.pop());
-};
-var rD = (t) => {
- const u = t.split(" ");
- let F = u.length;
- for (;F > 0 && !(A(u[F - 1]) > 0); )
- F--;
- return F === u.length ? t : u.slice(0, F).join(" ") + u.slice(F).join("");
-};
-var ED = (t, u, F = {}) => {
- if (F.trim !== false && t.trim() === "")
- return "";
- let e = "", s, C;
- const D = iD(t);
- let i = [""];
- for (const [E, h] of t.split(" ").entries()) {
- F.trim !== false && (i[i.length - 1] = i[i.length - 1].trimStart());
- let o = A(i[i.length - 1]);
- if (E !== 0 && (o >= u && (F.wordWrap === false || F.trim === false) &&
(i.push(""), o = 0), (o > 0 || F.trim === false) && (i[i.length - 1] += " ",
o++)), F.hard && D[E] > u) {
- const B = u - o, p = 1 + Math.floor((D[E] - B - 1) / u);
- Math.floor((D[E] - 1) / u) < p && i.push(""), y(i, h, u);
- continue;
- }
- if (o + D[E] > u && o > 0 && D[E] > 0) {
- if (F.wordWrap === false && o < u) {
- y(i, h, u);
- continue;
- }
- i.push("");
- }
- if (o + D[E] > u && F.wordWrap === false) {
- y(i, h, u);
- continue;
- }
- i[i.length - 1] += h;
- }
- F.trim !== false && (i = i.map((E) => rD(E)));
- const n = [...i.join(`
-`)];
- for (const [E, h] of n.entries()) {
- if (e += h, g.has(h)) {
- const { groups: B } = new
RegExp(`(?:\\${O}(?<code>\\d+)m|\\${w}(?<uri>.*)${b})`).exec(n.slice(E).join(""))
|| { groups: {} };
- if (B.code !== undefined) {
- const p = Number.parseFloat(B.code);
- s = p === sD ? undefined : p;
- } else
- B.uri !== undefined && (C = B.uri.length === 0 ? undefined : B.uri);
- }
- const o = eD.codes.get(Number(s));
- n[E + 1] === `
-` ? (C && (e += L("")), s && o && (e += N(o))) : h === `
-` && (s && o && (e += N(s)), C && (e += L(C)));
- }
- return e;
-};
-var oD = Object.defineProperty;
-var nD = (t, u, F) => (u in t) ? oD(t, u, { enumerable: true, configurable:
true, writable: true, value: F }) : t[u] = F;
-var a = (t, u, F) => (nD(t, typeof u != "symbol" ? u + "" : u, F), F);
-var V = Symbol("clack:cancel");
-var z = new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"]]);
-var lD = new Set(["up", "down", "left", "right", "space", "enter"]);
-
-class x {
- constructor({ render: u, input: F = $, output: e = k, ...s }, C = true) {
- a(this, "input"), a(this, "output"), a(this, "rl"), a(this, "opts"),
a(this, "_track", false), a(this, "_render"), a(this, "_cursor", 0), a(this,
"state", "initial"), a(this, "value"), a(this, "error", ""), a(this,
"subscribers", new Map), a(this, "_prevFrame", ""), this.opts = s,
this.onKeypress = this.onKeypress.bind(this), this.close =
this.close.bind(this), this.render = this.render.bind(this), this._render =
u.bind(this), this._track = C, this.input = F, this.output = e;
- }
- prompt() {
- const u = new U(0);
- return u._write = (F, e, s) => {
- this._track && (this.value = this.rl.line.replace(/\t/g, ""),
this._cursor = this.rl.cursor, this.emit("value", this.value)), s();
- }, this.input.pipe(u), this.rl = _.createInterface({ input: this.input,
output: u, tabSize: 2, prompt: "", escapeCodeTimeout: 50 }),
_.emitKeypressEvents(this.input, this.rl), this.rl.prompt(),
this.opts.initialValue !== undefined && this._track &&
this.rl.write(this.opts.initialValue), this.input.on("keypress",
this.onKeypress), v(this.input, true), this.output.on("resize", this.render),
this.render(), new Promise((F, e) => {
- this.once("submit", () => {
- this.output.write(import_sisteransi.cursor.show),
this.output.off("resize", this.render), v(this.input, false), F(this.value);
- }), this.once("cancel", () => {
- this.output.write(import_sisteransi.cursor.show),
this.output.off("resize", this.render), v(this.input, false), F(V);
- });
- });
- }
- on(u, F) {
- const e = this.subscribers.get(u) ?? [];
- e.push({ cb: F }), this.subscribers.set(u, e);
- }
- once(u, F) {
- const e = this.subscribers.get(u) ?? [];
- e.push({ cb: F, once: true }), this.subscribers.set(u, e);
- }
- emit(u, ...F) {
- const e = this.subscribers.get(u) ?? [], s = [];
- for (const C of e)
- C.cb(...F), C.once && s.push(() => e.splice(e.indexOf(C), 1));
- for (const C of s)
- C();
- }
- unsubscribe() {
- this.subscribers.clear();
- }
- onKeypress(u, F) {
- if (this.state === "error" && (this.state = "active"), F?.name &&
!this._track && z.has(F.name) && this.emit("cursor", z.get(F.name)), F?.name &&
lD.has(F.name) && this.emit("cursor", F.name), u && (u.toLowerCase() === "y" ||
u.toLowerCase() === "n") && this.emit("confirm", u.toLowerCase() === "y"), u
=== " " && this.opts.placeholder && (this.value ||
(this.rl.write(this.opts.placeholder), this.emit("value",
this.opts.placeholder))), u && this.emit("key", u.toLowerCase()), F?.name ==
[...]
- if (this.opts.validate) {
- const e = this.opts.validate(this.value);
- e && (this.error = e, this.state = "error", this.rl.write(this.value));
- }
- this.state !== "error" && (this.state = "submit");
- }
- u === "" && (this.state = "cancel"), (this.state === "submit" ||
this.state === "cancel") && this.emit("finalize"), this.render(), (this.state
=== "submit" || this.state === "cancel") && this.close();
- }
- close() {
- this.input.unpipe(), this.input.removeListener("keypress",
this.onKeypress), this.output.write(`
-`), v(this.input, false), this.rl.close(), this.emit(`${this.state}`,
this.value), this.unsubscribe();
- }
- restoreCursor() {
- const u = R(this._prevFrame, process.stdout.columns, { hard: true
}).split(`
-`).length - 1;
- this.output.write(import_sisteransi.cursor.move(-999, u * -1));
- }
- render() {
- const u = R(this._render(this) ?? "", process.stdout.columns, { hard: true
});
- if (u !== this._prevFrame) {
- if (this.state === "initial")
- this.output.write(import_sisteransi.cursor.hide);
- else {
- const F = aD(this._prevFrame, u);
- if (this.restoreCursor(), F && F?.length === 1) {
- const e = F[0];
- this.output.write(import_sisteransi.cursor.move(0, e)),
this.output.write(import_sisteransi.erase.lines(1));
- const s = u.split(`
-`);
- this.output.write(s[e]), this._prevFrame = u,
this.output.write(import_sisteransi.cursor.move(0, s.length - e - 1));
- return;
- } else if (F && F?.length > 1) {
- const e = F[0];
- this.output.write(import_sisteransi.cursor.move(0, e)),
this.output.write(import_sisteransi.erase.down());
- const s = u.split(`
-`).slice(e);
- this.output.write(s.join(`
-`)), this._prevFrame = u;
- return;
- }
- this.output.write(import_sisteransi.erase.down());
- }
- this.output.write(u), this.state === "initial" && (this.state =
"active"), this._prevFrame = u;
- }
- }
-}
-var vD = Object.defineProperty;
-var dD = (t, u, F) => (u in t) ? vD(t, u, { enumerable: true, configurable:
true, writable: true, value: F }) : t[u] = F;
-var Y = (t, u, F) => (dD(t, typeof u != "symbol" ? u + "" : u, F), F);
-
-class mD extends x {
- constructor({ mask: u, ...F }) {
- super(F), Y(this, "valueWithCursor", ""), Y(this, "_mask", "\u2022"),
this._mask = u ?? "\u2022", this.on("finalize", () => {
- this.valueWithCursor = this.masked;
- }), this.on("value", () => {
- if (this.cursor >= this.value.length)
- this.valueWithCursor =
`${this.masked}${import_picocolors.default.inverse(import_picocolors.default.hidden("_"))}`;
- else {
- const e = this.masked.slice(0, this.cursor), s =
this.masked.slice(this.cursor);
- this.valueWithCursor =
`${e}${import_picocolors.default.inverse(s[0])}${s.slice(1)}`;
- }
- });
- }
- get cursor() {
- return this._cursor;
- }
- get masked() {
- return this.value.replaceAll(/./g, this._mask);
- }
-}
-var bD = Object.defineProperty;
-var wD = (t, u, F) => (u in t) ? bD(t, u, { enumerable: true, configurable:
true, writable: true, value: F }) : t[u] = F;
-var Z = (t, u, F) => (wD(t, typeof u != "symbol" ? u + "" : u, F), F);
-var yD = class extends x {
- constructor(u) {
- super(u, false), Z(this, "options"), Z(this, "cursor", 0), this.options =
u.options, this.cursor = this.options.findIndex(({ value: F }) => F ===
u.initialValue), this.cursor === -1 && (this.cursor = 0), this.changeValue(),
this.on("cursor", (F) => {
- switch (F) {
- case "left":
- case "up":
- this.cursor = this.cursor === 0 ? this.options.length - 1 :
this.cursor - 1;
- break;
- case "down":
- case "right":
- this.cursor = this.cursor === this.options.length - 1 ? 0 :
this.cursor + 1;
- break;
- }
- this.changeValue();
- });
- }
- get _value() {
- return this.options[this.cursor];
- }
- changeValue() {
- this.value = this._value.value;
- }
-};
-var SD = Object.defineProperty;
-var jD = (t, u, F) => (u in t) ? SD(t, u, { enumerable: true, configurable:
true, writable: true, value: F }) : t[u] = F;
-var MD = (t, u, F) => (jD(t, typeof u != "symbol" ? u + "" : u, F), F);
-
-class TD extends x {
- constructor(u) {
- super(u), MD(this, "valueWithCursor", ""), this.on("finalize", () => {
- this.value || (this.value = u.defaultValue), this.valueWithCursor =
this.value;
- }), this.on("value", () => {
- if (this.cursor >= this.value.length)
- this.valueWithCursor =
`${this.value}${import_picocolors.default.inverse(import_picocolors.default.hidden("_"))}`;
- else {
- const F = this.value.slice(0, this.cursor), e =
this.value.slice(this.cursor);
- this.valueWithCursor =
`${F}${import_picocolors.default.inverse(e[0])}${e.slice(1)}`;
- }
- });
- }
- get cursor() {
- return this._cursor;
- }
-}
-var PD = globalThis.process.platform.startsWith("win");
-
-// node_modules/@clack/prompts/dist/index.mjs
-var import_picocolors2 = __toESM(require_picocolors(), 1);
-var import_sisteransi2 = __toESM(require_src(), 1);
-import h from "process";
-function q2() {
- return h.platform !== "win32" ? h.env.TERM !== "linux" : Boolean(h.env.CI)
|| Boolean(h.env.WT_SESSION) || Boolean(h.env.TERMINUS_SUBLIME) ||
h.env.ConEmuTask === "{cmd::Cmder}" || h.env.TERM_PROGRAM ===
"Terminus-Sublime" || h.env.TERM_PROGRAM === "vscode" || h.env.TERM ===
"xterm-256color" || h.env.TERM === "alacritty" || h.env.TERMINAL_EMULATOR ===
"JetBrains-JediTerm";
-}
-var _2 = q2();
-var o = (r2, n) => _2 ? r2 : n;
-var H = o("\u25C6", "*");
-var I2 = o("\u25A0", "x");
-var x2 = o("\u25B2", "x");
-var S2 = o("\u25C7", "o");
-var K = o("\u250C", "T");
-var a2 = o("\u2502", "|");
-var d2 = o("\u2514", "\u2014");
-var b2 = o("\u25CF", ">");
-var E = o("\u25CB", " ");
-var C = o("\u25FB", "[\u2022]");
-var w2 = o("\u25FC", "[+]");
-var M2 = o("\u25FB", "[ ]");
-var U2 = o("\u25AA", "\u2022");
-var B = o("\u2500", "-");
-var Z2 = o("\u256E", "+");
-var z2 = o("\u251C", "+");
-var X2 = o("\u256F", "+");
-var J2 = o("\u25CF", "\u2022");
-var Y2 = o("\u25C6", "*");
-var Q2 = o("\u25B2", "!");
-var ee = o("\u25A0", "x");
-var y2 = (r2) => {
- switch (r2) {
- case "initial":
- case "active":
- return import_picocolors2.default.cyan(H);
- case "cancel":
- return import_picocolors2.default.red(I2);
- case "error":
- return import_picocolors2.default.yellow(x2);
- case "submit":
- return import_picocolors2.default.green(S2);
- }
-};
-var te = (r2) => new TD({ validate: r2.validate, placeholder: r2.placeholder,
defaultValue: r2.defaultValue, initialValue: r2.initialValue, render() {
- const n = `${import_picocolors2.default.gray(a2)}
-${y2(this.state)} ${r2.message}
-`, i = r2.placeholder ? import_picocolors2.default.inverse(r2.placeholder[0])
+ import_picocolors2.default.dim(r2.placeholder.slice(1)) :
import_picocolors2.default.inverse(import_picocolors2.default.hidden("_")), t =
this.value ? this.valueWithCursor : i;
- switch (this.state) {
- case "error":
- return `${n.trim()}
-${import_picocolors2.default.yellow(a2)} ${t}
-${import_picocolors2.default.yellow(d2)}
${import_picocolors2.default.yellow(this.error)}
-`;
- case "submit":
- return `${n}${import_picocolors2.default.gray(a2)}
${import_picocolors2.default.dim(this.value || r2.placeholder)}`;
- case "cancel":
- return `${n}${import_picocolors2.default.gray(a2)}
${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(this.value
?? ""))}${this.value?.trim() ? `
-` + import_picocolors2.default.gray(a2) : ""}`;
- default:
- return `${n}${import_picocolors2.default.cyan(a2)} ${t}
-${import_picocolors2.default.cyan(d2)}
-`;
- }
-} }).prompt();
-var re = (r2) => new mD({ validate: r2.validate, mask: r2.mask ?? U2, render()
{
- const n = `${import_picocolors2.default.gray(a2)}
-${y2(this.state)} ${r2.message}
-`, i = this.valueWithCursor, t = this.masked;
- switch (this.state) {
- case "error":
- return `${n.trim()}
-${import_picocolors2.default.yellow(a2)} ${t}
-${import_picocolors2.default.yellow(d2)}
${import_picocolors2.default.yellow(this.error)}
-`;
- case "submit":
- return `${n}${import_picocolors2.default.gray(a2)}
${import_picocolors2.default.dim(t)}`;
- case "cancel":
- return `${n}${import_picocolors2.default.gray(a2)}
${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(t ??
""))}${t ? `
-` + import_picocolors2.default.gray(a2) : ""}`;
- default:
- return `${n}${import_picocolors2.default.cyan(a2)} ${i}
-${import_picocolors2.default.cyan(d2)}
-`;
- }
-} }).prompt();
-var ie = (r2) => {
- const n = (t, s) => {
- const c2 = t.label ?? String(t.value);
- return s === "active" ? `${import_picocolors2.default.green(b2)} ${c2}
${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}` : s ===
"selected" ? `${import_picocolors2.default.dim(c2)}` : s === "cancelled" ?
`${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(c2))}`
: `${import_picocolors2.default.dim(E)} ${import_picocolors2.default.dim(c2)}`;
- };
- let i = 0;
- return new yD({ options: r2.options, initialValue: r2.initialValue, render()
{
- const t = `${import_picocolors2.default.gray(a2)}
-${y2(this.state)} ${r2.message}
-`;
- switch (this.state) {
- case "submit":
- return `${t}${import_picocolors2.default.gray(a2)}
${n(this.options[this.cursor], "selected")}`;
- case "cancel":
- return `${t}${import_picocolors2.default.gray(a2)}
${n(this.options[this.cursor], "cancelled")}
-${import_picocolors2.default.gray(a2)}`;
- default: {
- const s = r2.maxItems === undefined ? 1 / 0 : Math.max(r2.maxItems, 5);
- this.cursor >= i + s - 3 ? i = Math.max(Math.min(this.cursor - s + 3,
this.options.length - s), 0) : this.cursor < i + 2 && (i = Math.max(this.cursor
- 2, 0));
- const c2 = s < this.options.length && i > 0, l2 = s <
this.options.length && i + s < this.options.length;
- return `${t}${import_picocolors2.default.cyan(a2)}
${this.options.slice(i, i + s).map((u, m2, $2) => m2 === 0 && c2 ?
import_picocolors2.default.dim("...") : m2 === $2.length - 1 && l2 ?
import_picocolors2.default.dim("...") : n(u, m2 + i === this.cursor ? "active"
: "inactive")).join(`
-${import_picocolors2.default.cyan(a2)} `)}
-${import_picocolors2.default.cyan(d2)}
-`;
- }
- }
- } }).prompt();
-};
-var ue = (r2 = "") => {
- process.stdout.write(`${import_picocolors2.default.gray(d2)}
${import_picocolors2.default.red(r2)}
-
-`);
-};
-var oe = (r2 = "") => {
- process.stdout.write(`${import_picocolors2.default.gray(K)} ${r2}
-`);
-};
-var $e = (r2 = "") => {
- process.stdout.write(`${import_picocolors2.default.gray(a2)}
-${import_picocolors2.default.gray(d2)} ${r2}
-
-`);
-};
-
-// configurator.ts
-var import_picocolors3 = __toESM(require_picocolors(), 1);
-import {parseArgs} from "util";
-async function askMissingData(missingData, override = false) {
- if (Object.keys(missingData).length === 0) {
- $e("Configuration set from ops");
- process.exit(0);
- }
- console.log();
- if (!override) {
- console.log("Configuration partially set from ops. Need a few more:");
- }
- for (const key in missingData) {
- let inputFromPrompt;
- const prompt = missingData[key];
- if (Array.isArray(prompt.type)) {
- const defaultValueOK = prompt.default &&
prompt.type.includes(prompt.default);
- if (prompt.default && !defaultValueOK) {
- console.log();
- console.warn(`The default value ${prompt.default} is not in the enum
values.`);
- }
- const selected = await ie({
- message: prompt.label || `Pick a value for '${key}'`,
- options: prompt.type.map((v2) => ({ label: v2, value: v2 })),
- initialValue: defaultValueOK ? prompt.default : undefined
- });
- if (!selected || hD(selected)) {
- ue("Operation cancelled");
- process.exit(0);
- }
- inputFromPrompt = selected.toString();
- } else if (prompt.type === "bool") {
- const selected = await ie({
- initialValue: prompt.default === "true" || prompt.default === true ?
"true" : "false",
- message: prompt.label || `Pick a true/false for '${key}'`,
- options: [
- { label: "true", value: "true" },
- { label: "false", value: "false" }
- ]
- });
- if (!selected || hD(selected)) {
- ue("Operation cancelled");
- process.exit(0);
- }
- inputFromPrompt = selected.toString();
- } else if (prompt.type === "password") {
- if (prompt.default) {
- console.log();
- console.warn("Default password value is not supported. Please enter
the password manually.");
- }
- const input = await re({
- message: prompt.label || `Enter password value for ${key}`,
- validate: (value) => {
- if (!value) {
- return "Password cannot be empty";
- }
- }
- });
- if (hD(input)) {
- ue("Operation cancelled");
- process.exit(0);
- }
- inputFromPrompt = input;
- } else {
- const defaultMsgFragment = prompt.default ? `(default:
${prompt.default})` : "";
- const message = `Enter value for ${key} ${defaultMsgFragment}
(${prompt.type})`;
- let input = await te({
- message: prompt.label || message,
- initialValue: prompt.default?.toString(),
- validate: (value) => {
- switch (prompt.type) {
- case "int":
- if (!Number.isInteger(Number(value))) {
- return `Value for ${key} must be an integer number`;
- }
- break;
- case "float":
- if (!Number(value)) {
- return `Value for ${key} must be a number`;
- }
- }
- return;
- }
- });
- if (hD(input)) {
- ue("Operation cancelled");
- process.exit(0);
- }
- inputFromPrompt = input;
- }
- console.log(`Setting ${key} to ${inputFromPrompt}`);
- const { exitCode, stderr } = await $2`${OPS} -config
${key}=${inputFromPrompt}`.nothrow();
- if (exitCode !== 0) {
- ue(stderr.toString());
- return process.exit(1);
- }
- }
-}
-function findMissingConfig(config, opsCurrentConfig) {
- let newConfig = {};
- let opsConfigKeys = opsCurrentConfig.split("\n").map((line) =>
line.split("=")[0]);
- for (const key in config) {
- if (opsConfigKeys.includes(key)) {
- continue;
- }
- newConfig[key] = config[key];
- }
- return newConfig;
-}
-function readPositionalFile(positionals) {
- if (positionals.length < 2) {
- console.error("This should not happen");
- return { success: false, message: "This should not happen" };
- }
- if (positionals.length === 2) {
- return { success: true, help: HelpMsg };
- }
- if (positionals.length > 3) {
- return {
- success: true,
- message: AdditionalArgsMsg,
- jsonFilePath: positionals[2]
- };
- }
- return { success: true, jsonFilePath: positionals[2] };
-}
-async function parsePositionalFile(path) {
- const file = Bun.file(Bun.pathToFileURL(path));
- if (!await file.exists()) {
- return { success: false, message: FileNotFoundJsonMsg +
Bun.pathToFileURL(path) };
- }
- try {
- const contents = await file.json();
- return { success: true, body: contents };
- } catch (error) {
- return { success: false, message: NotValidJsonMsg };
- }
-}
-function isInputConfigValid(body) {
- if (Object.keys(body).length === 0) {
- return false;
- }
- for (const key in body) {
- const value = body[key];
- if (typeof value !== "object") {
- return false;
- }
- if (!value.type) {
- return false;
- }
- if (!["string", "int", "float", "bool", "password"].includes(value.type)
&& !Array.isArray(value.type)) {
- return false;
- }
- }
- for (const key in body) {
- if (!/^[A-Z][A-Z_]|[0-9]*[A-Z]|[0-9]$/.test(key)) {
- return false;
- }
- }
- return true;
-}
-var OPS = process.env.OPS || "ops";
-var AdditionalArgsMsg = "Additional arguments will be ignored.";
-var NotValidJsonMsg = "Not a valid JSON file";
-var FileNotFoundJsonMsg = "The JSON file was not found. Pathname: ";
-var BadConfigMsg = "Bad configuration file. Check the help message (-h) to see
the expected format.";
-var HelpMsg = `
-Usage: config <configjson> [-o | --override]
-
-Description:
-Prompt the user for configuration data defined in the config.json file.
-The script will ignore the keys from the input config that are already set in
ops
-and only prompt the user for the missing data, unless the override flag is
set.
-Then they will be saved in the ops config.
-
-The config.json file must be a JSON file with the following structure:
-
- {
- "KEY": {
- "type": "string"
- },
- "OTHER_KEY": {
- "label": "An optional custom message",
- "type": "int"
- },
- ...
- }
-
-The keys must be uppercase words (separated by underscores).
-The value for the "type" key must be either string with the following values:
-- string
-- int
-- float
-- bool
-- password
-- an array of strings with specific values (an enum).
-`;
-async function main() {
- const options = {
- showhelp: {
- type: "boolean"
- },
- override: {
- type: "boolean"
- }
- };
- const { values, positionals } = parseArgs({
- args: Bun.argv,
- options,
- strict: true,
- allowPositionals: true
- });
- if (values.showhelp) {
- console.log(HelpMsg);
- return process.exit(0);
- }
- const override = values.override || false;
- const readPosRes = readPositionalFile(positionals);
- if (!readPosRes.success) {
- ue(readPosRes.message);
- return process.exit(1);
- }
- if (readPosRes.help) {
- console.log(readPosRes.help);
- return process.exit(0);
- }
- if (readPosRes.message) {
- console.warn(readPosRes.message);
- }
- const jsonRes = await parsePositionalFile(readPosRes.jsonFilePath);
- if (!jsonRes.success) {
- ue(jsonRes.message);
- return process.exit(1);
- }
- const config = jsonRes.body;
- if (!isInputConfigValid(config)) {
- ue(BadConfigMsg);
- return process.exit(1);
- }
- const { exitCode, stderr, stdout } = await $2`${OPS} -config -d`.quiet();
- if (exitCode !== 0) {
- ue(stderr.toString());
- return process.exit(1);
- }
- const opsCurrentConfig = stdout.toString();
- let missingData = config;
- if (!override) {
- missingData = findMissingConfig(config, opsCurrentConfig);
- }
- console.log();
- oe(import_picocolors3.default.inverse(" ops configurator "));
- await askMissingData(missingData, override);
- console.log();
- $e("You're all set!");
-}
-
-// index.ts
-main().catch(console.error);
diff --git a/util/config/configurator/bun.lock
b/util/config/configurator/bun.lock
deleted file mode 100644
index 9031cbc..0000000
--- a/util/config/configurator/bun.lock
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- "lockfileVersion": 1,
- "configVersion": 0,
- "workspaces": {
- "": {
- "name": "prompt",
- "dependencies": {
- "@clack/prompts": "^0.7.0",
- },
- "devDependencies": {
- "@types/bun": "latest",
- },
- "peerDependencies": {
- "typescript": "^5.0.0",
- },
- },
- },
- "packages": {
- "@clack/core": ["@clack/[email protected]", "", { "dependencies": { "picocolors":
"^1.0.0", "sisteransi": "^1.0.5" } },
"sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw=="],
-
- "@clack/prompts": ["@clack/[email protected]", "", { "dependencies": {
"@clack/core": "^0.3.3", "is-unicode-supported": "*", "picocolors": "^1.0.0",
"sisteransi": "^1.0.5" } },
"sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA=="],
-
- "@types/bun": ["@types/[email protected]", "", { "dependencies": { "bun-types":
"1.1.17" } },
"sha512-uJgKjTdX0GkWEHZzQzFsJkWp5+43ZS7HC8sZPFnOwnSo1AsNl2q9o2bFeS23disNDqbggEgyFkKCHl/w8iZsMA=="],
-
- "@types/node": ["@types/[email protected]", "", { "dependencies": {
"undici-types": "~5.26.4" } },
"sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg=="],
-
- "@types/ws": ["@types/[email protected]", "", { "dependencies": { "@types/node":
"*" } },
"sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ=="],
-
- "bun-types": ["[email protected]", "", { "dependencies": { "@types/node":
"~20.12.8", "@types/ws": "~8.5.10" } },
"sha512-Z4+OplcSd/YZq7ZsrfD00DKJeCwuNY96a1IDJyR73+cTBaFIS7SC6LhpY/W3AMEXO9iYq5NJ58WAwnwL1p5vKg=="],
-
- "is-unicode-supported": ["[email protected]", "", {},
"sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q=="],
-
- "picocolors": ["[email protected]", "", {},
"sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="],
-
- "sisteransi": ["[email protected]", "", {},
"sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
-
- "typescript": ["[email protected]", "", { "bin": { "tsc": "bin/tsc",
"tsserver": "bin/tsserver" } },
"sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q=="],
-
- "undici-types": ["[email protected]", "", {},
"sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
- }
-}
diff --git a/util/config/configurator/configurator.ts
b/util/config/configurator/configurator.ts
deleted file mode 100644
index 70a5f13..0000000
--- a/util/config/configurator/configurator.ts
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { $ } from "bun";
-
-import {
- intro,
- outro,
- select,
- isCancel,
- cancel,
- text,
- password,
-} from "@clack/prompts";
-import color from "picocolors";
-
-import { parseArgs } from "util";
-
-type Prompts = Record<string, PromptData>;
-
-type PromptData = {
- label?: string;
- type: string | string[];
- default?: string;
- value?: string;
-};
-
-const OPS = process.env.OPS || "ops";
-
-export const AdditionalArgsMsg = "Additional arguments will be ignored.";
-export const NotValidJsonMsg = "Not a valid JSON file";
-export const FileNotFoundJsonMsg = "The JSON file was not found. Pathname: ";
-export const BadConfigMsg =
- "Bad configuration file. Check the help message (-h) to see the expected
format.";
-
-export const HelpMsg = `
-Usage: config <configjson> [-o | --override]
-
-Description:
-Prompt the user for configuration data defined in the config.json file.
-The script will ignore the keys from the input config that are already set in
ops
-and only prompt the user for the missing data, unless the override flag is
set.
-Then they will be saved in the ops config. You can also define a default value.
-
-The config.json file must be a JSON file with the following structure:
-
- {
- "KEY": {
- "type": "string"
- },
- "OTHER_KEY": {
- "label": "An optional custom message",
- "type": "int",
- "default": "42"
- },
- ...
- }
-
-The keys must be uppercase words (separated by underscores).
-The value for the "type" key must be either string with the following values:
-- string
-- int
-- float
-- bool
-- password
-- an array of strings with specific values (an enum).
-`;
-
-export default async function main() {
- const options: { showhelp: { type: 'boolean' }, override: { type: 'boolean'
} } = {
- showhelp: {
- type: 'boolean',
- },
- override: {
- type: 'boolean',
- },
- };
- const { values, positionals } = parseArgs({
- args: Bun.argv,
- options: options,
- strict: true,
- allowPositionals: true,
-
- });
-
- if (values.showhelp) {
- console.log(HelpMsg);
- return process.exit(0);
- }
-
- const override = values.override || false;
-
- // 1. Read input config json
- const readPosRes = readPositionalFile(positionals);
- if (!readPosRes.success) {
- cancel(readPosRes.message);
- return process.exit(1);
- }
-
- if (readPosRes.help) {
- console.log(readPosRes.help);
- return process.exit(0);
- }
-
- if (readPosRes.message) {
- console.warn(readPosRes.message);
- }
-
- // 2. Parse the json
- const jsonRes = await parsePositionalFile(readPosRes.jsonFilePath!);
-
- if (!jsonRes.success) {
- cancel(jsonRes.message);
- return process.exit(1);
- }
-
- const config = jsonRes.body;
-
- // 3. Validate the given config json
- if (!isInputConfigValid(config)) {
- cancel(BadConfigMsg);
- return process.exit(1);
- }
-
- // 4. Run OPS to get the available config data
- const { exitCode, stderr, stdout } = await $`${OPS} -config -d`.quiet();
- if (exitCode !== 0) {
- cancel(stderr.toString());
- return process.exit(1);
- }
-
- const opsCurrentConfig = stdout.toString();
-
- // 5. Remove the keys from config that are already in the opsConfig
- let missingData = config;
- if (!override) {
- missingData = findMissingConfig(config, opsCurrentConfig);
- }
-
- // 6. Ask the user for the missing data
- console.log();
- intro(color.inverse(" ops configurator "));
-
- await askMissingData(missingData, override);
-
- // 7. Save the data to the config?
- console.log();
-
- outro("You're all set!");
-}
-
-async function askMissingData(missingData: Prompts, override: boolean = false)
{
- if (Object.keys(missingData).length === 0) {
- outro("Configuration set from ops");
- process.exit(0);
- }
- console.log();
-
- if (!override) {
- console.log("Configuration partially set from ops. Need a few more:");
- }
-
- for (const key in missingData) {
- let inputFromPrompt: string;
- const prompt: PromptData = missingData[key];
- // let askedForPassword = false;
-
- if (Array.isArray(prompt.type)) {
- const defaultValueOK = prompt.default &&
prompt.type.includes(prompt.default);
- if (prompt.default && !defaultValueOK) {
- console.log();
- console.warn(`The default value ${prompt.default} is not in the enum
values.`);
- }
-
- const selected = await select({
- message: prompt.label || `Pick a value for '${key}'`,
- options: prompt.type.map((v) => ({ label: v, value: v })),
- initialValue: defaultValueOK ? prompt.default : undefined,
- });
-
- if (!selected || isCancel(selected)) {
- cancel("Operation cancelled");
- process.exit(0);
- }
-
- inputFromPrompt = selected.toString();
-
- // inputConfigs[key] = { ...prompt, value: selected.toString() };
- } else if (prompt.type === "bool") {
- const selected = await select({
- initialValue: prompt.default === "true" || prompt.default as unknown
as boolean === true ? "true" : "false",
- message: prompt.label || `Pick a true/false for '${key}'`,
- options: [
- { label: "true", value: "true" },
- { label: "false", value: "false" },
- ],
- });
-
- if (!selected || isCancel(selected)) {
- cancel("Operation cancelled");
- process.exit(0);
- }
-
- inputFromPrompt = selected.toString();
- // inputConfigs[key] = { ...prompt, value: selected.toString() };
- } else if (prompt.type === "password") {
- if (prompt.default) {
- console.log();
- console.warn("Default password value is not supported. Please enter
the password manually.");
- }
- const input = await password({
- message: prompt.label || `Enter password value for ${key}`,
- validate: (value) => {
- if (!value) {
- return "Password cannot be empty";
- }
- }
- });
-
- if (isCancel(input)) {
- cancel("Operation cancelled");
- process.exit(0);
- }
- inputFromPrompt = input;
- // askedForPassword = true;
- } else {
- const defaultMsgFragment = prompt.default ? `(default:
${prompt.default})` : "";
- const message = `Enter value for ${key} ${defaultMsgFragment}
(${prompt.type})`;
-
- let input = await text({
- message: prompt.label || message,
- // defaultValue: prompt.default?.toString(),
- initialValue: prompt.default?.toString(),
- validate: (value) => {
- switch (prompt.type) {
- case "int":
- if (!Number.isInteger(Number(value))) {
- return `Value for ${key} must be an integer number`;
- }
- break;
- case "float":
- if (!Number(value)) {
- return `Value for ${key} must be a number`;
- }
- }
- return;
- }
- }) as string;
-
- if (isCancel(input)) {
- cancel("Operation cancelled");
- process.exit(0);
- }
-
-
- inputFromPrompt = input;
- // inputConfigs[key] = { ...prompt, value: input };
- }
-
- // if (!askedForPassword) {
- // console.log("Setting", key, "to", inputFromPrompt);
- // } else {
- // console.log("Setting", key, "to", "*".repeat(inputFromPrompt.length));
- // }
-
- console.log(`Setting ${key} to ${inputFromPrompt}`);
- const { exitCode, stderr } =
- await $`${OPS} -config ${key}=${inputFromPrompt}`.nothrow();
- if (exitCode !== 0) {
- cancel(stderr.toString());
- return process.exit(1);
- }
- }
-}
-
-export function findMissingConfig(
- config: Record<string, any>,
- opsCurrentConfig: string
-): Prompts {
- let newConfig: Record<string, any> = {};
-
- let opsConfigKeys = opsCurrentConfig.split("\n").map((line) =>
line.split("=")[0]);
-
- for (const key in config) {
- if (opsConfigKeys.includes(key)) {
- continue;
- }
- newConfig[key] = config[key];
- }
-
- return newConfig;
-}
-
-export function readPositionalFile(positionals: string[]): {
- success: boolean;
- message?: string;
- help?: string;
- jsonFilePath?: string;
-} {
-
- if (positionals.length < 2) {
- console.error("This should not happen");
- return { success: false, message: "This should not happen" };
- }
-
- if (positionals.length === 2) {
- return { success: true, help: HelpMsg };
- }
-
- if (positionals.length > 3) {
- return {
- success: true,
- message: AdditionalArgsMsg,
- jsonFilePath: positionals[2],
- };
- }
-
- return { success: true, jsonFilePath: positionals[2] };
-}
-
-export async function parsePositionalFile(
- path: string
-): Promise<{ success: boolean; message?: string; body?: any }> {
-
- const file = Bun.file(Bun.pathToFileURL(path));
-
- if (!await file.exists()) {
- return { success: false, message: FileNotFoundJsonMsg +
Bun.pathToFileURL(path) };
- }
-
-
- try {
- const contents = await file.json();
- return { success: true, body: contents };
- } catch (error) {
- return { success: false, message: NotValidJsonMsg };
- }
-}
-
-export function isInputConfigValid(body: Record<string, any>): boolean {
- // 1. If the body is empty, return false
- if (Object.keys(body).length === 0) {
- return false;
- }
-
- // 2. Check that each key in the body has the keys as the Prompt type
- for (const key in body) {
- const value = body[key];
- if (typeof value !== "object") {
- return false;
- }
-
- if (!value.type) {
- return false;
- }
-
- if (
- !["string", "int", "float", "bool", "password"].includes(value.type) &&
- !Array.isArray(value.type)
- ) {
- return false;
- }
- }
-
- // 3. Check that all the keys are uppercase and can only have underscores
not at the beginning or end
- for (const key in body) {
- if (!/^[A-Z][A-Z_]|[0-9]*[A-Z]|[0-9]$/.test(key)) {
- return false;
- }
- }
-
- return true;
-}
diff --git a/util/config/configurator/index.ts
b/util/config/configurator/index.ts
deleted file mode 100644
index 18e0159..0000000
--- a/util/config/configurator/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import main from "./configurator";
-
-main().catch(console.error);
diff --git a/util/config/configurator/package.json
b/util/config/configurator/package.json
deleted file mode 100644
index bbd833c..0000000
--- a/util/config/configurator/package.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "prompt",
- "module": "index.ts",
- "type": "module",
- "scripts": {
- "start": "bun index.ts",
- "test": "bun test tests/index.test.ts",
- "build": "bun build --target=bun index.ts > configurator.js && mv
configurator.js ../configurator.js"
- },
- "devDependencies": {
- "@types/bun": "latest"
- },
- "peerDependencies": {
- "typescript": "^5.0.0"
- },
- "dependencies": {
- "@clack/prompts": "^0.7.0"
- }
-}
diff --git a/util/config/configurator/tests/fixtures/bad.json
b/util/config/configurator/tests/fixtures/bad.json
deleted file mode 100644
index ff30235..0000000
--- a/util/config/configurator/tests/fixtures/bad.json
+++ /dev/null
@@ -1 +0,0 @@
-}
\ No newline at end of file
diff --git a/util/config/configurator/tests/fixtures/multi-keys.json
b/util/config/configurator/tests/fixtures/multi-keys.json
deleted file mode 100644
index 9ba80cf..0000000
--- a/util/config/configurator/tests/fixtures/multi-keys.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "HELLO": {
- "label": "Set a greeting",
- "type": "string"
- },
- "TESTINT": {
- "type": "int"
- },
- "TESTFLOAT": {
- "label": "Set a float",
- "type": "float"
- },
- "TESTBOOL": {
- "type": "bool"
- },
- "TESTPASSWORD": {
- "type": "password"
- },
- "TESTSELECT": {
- "type": ["one", "two", "three", "four options"]
- }
-}
diff --git a/util/config/configurator/tests/fixtures/not-json.txt
b/util/config/configurator/tests/fixtures/not-json.txt
deleted file mode 100644
index 13a8339..0000000
--- a/util/config/configurator/tests/fixtures/not-json.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
diff --git a/util/config/configurator/tests/fixtures/valid.json
b/util/config/configurator/tests/fixtures/valid.json
deleted file mode 100644
index 50a753e..0000000
--- a/util/config/configurator/tests/fixtures/valid.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "HELLO": {
- "type": "string"
- },
- "HELLO3": {
- "type": "string"
- },
- "ANOTHER": {
- "type": "string"
- }
-}
diff --git a/util/config/configurator/tests/fixtures/with-defaults.json
b/util/config/configurator/tests/fixtures/with-defaults.json
deleted file mode 100644
index ff94d44..0000000
--- a/util/config/configurator/tests/fixtures/with-defaults.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "HELLO": {
- "type": "string",
- "default": "world"
- },
- "HELLO3": {
- "type": "int",
- "default": 3
- },
- "A_FLOAT": {
- "type": "float",
- "default": 3.14
- },
- "A_BOOL": {
- "type": "bool",
- "default": false
- },
- "A_PASSWORD": {
- "type": "password",
- "default": "mypass"
- },
- "A_SELECT": {
- "type": ["one", "two", "three", "four options"],
- "default": "two"
- }
-}
diff --git a/util/config/configurator/tests/index.test.ts
b/util/config/configurator/tests/index.test.ts
deleted file mode 100644
index 20f6acd..0000000
--- a/util/config/configurator/tests/index.test.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { expect, test, describe } from "bun:test";
-import {
- readPositionalFile,
- parsePositionalFile,
- NotValidJsonMsg,
- HelpMsg,
- AdditionalArgsMsg,
- isInputConfigValid,
- findMissingConfig,
- FileNotFoundJsonMsg,
-} from "../configurator.ts";
-
-describe("findMissingConfig", () => {
- test("config has some opsConfig key", async () => {
- const config: any = { hello: "world", world: "hello" };
- const opsConfig = "hello=world";
- const newC: any = findMissingConfig(config, opsConfig);
- expect(newC).toEqual({ world: "hello" });
- });
-
- test("config has no opsConfig key", async () => {
- const config: any = { hello: "world", world: "hello" };
- const opsConfig = "not=existing";
- const newC: any = findMissingConfig(config, opsConfig);
- expect(newC).toEqual({ hello: "world", world: "hello" });
- });
-
- test("opsConfig has no key", async () => {
- const config: any = { hello: "world", world: "hello" };
- const opsConfig = "";
- const newC: any = findMissingConfig(config, opsConfig);
- expect(newC).toEqual({ hello: "world", world: "hello" });
- });
-
- test("config and opsConfig are the same", async () => {
- const config: any = { hello: "world", world: "hello" };
- const opsConfig = "hello=world\nworld=hello";
- const newC = findMissingConfig(config, opsConfig);
- expect(newC).toEqual({});
- });
-});
-
-describe("validateConfigJson", () => {
- test("empty config", async () => {
- const res = isInputConfigValid({});
- expect(res).toBe(false);
- });
-
- test("wrong json", async () => {
- const res = isInputConfigValid({
- some: "key",
- properties: { hello: { type: "string" } },
- });
- expect(res).toBe(false);
- });
-
- test("valid json", async () => {
- const res = isInputConfigValid({
- HELLO: { type: "string" },
- HELLO3: { type: "string" },
- HELLO33: { type: "string" },
- HELLO_3: { type: "string" },
- HELLO_33: { type: "string" },
- HELLO_A_1_B_2: { type: "string" },
- HELLO_A1B2: { type: "string" },
- HELLO_INT: { type: "int" },
- HELLO_FLOAT: { type: "float" },
- HELLO_BOOL: { type: "bool" },
- HELLOPASS: { type: "password" },
- HELLOENUM: { type: ["a", "b", "c"] },
- HELLOENUM3: { type: ["a", "b", "c"] },
- });
- expect(res).toBe(true);
- });
-});
-
-describe("readPositionalFile", () => {
- test("no positional arg provided", async () => {
- const res = readPositionalFile(["bun", "index.ts"]);
- expect(res.success).toBe(true);
- expect(res.help).toBe(HelpMsg);
- });
-
- test("too many positional arg provided", async () => {
- const res = readPositionalFile(["bun", "index.ts", "config.json",
"extra"]);
- expect(res.success).toBe(true);
- expect(res.jsonFilePath).toBe("config.json");
- expect(res.message).toBe(AdditionalArgsMsg);
- });
-
- test("positional arg provided", async () => {
- const res = readPositionalFile(["bun", "index.ts", "config.json"]);
- expect(res.success).toBe(true);
- expect(res.jsonFilePath).toBe("config.json");
- });
-});
-
-describe("parsePositionalFile", () => {
- test("file does not exist", async () => {
- const filename = "not-existing.json";
- const jsonRes = await parsePositionalFile(filename);
- expect(jsonRes.success).toBe(false);
- expect(jsonRes.message).toBe(FileNotFoundJsonMsg +
Bun.pathToFileURL(filename));
- });
-
- test("not a json file", async () => {
- const jsonRes = await parsePositionalFile("tests/fixtures/not-json.txt");
- expect(jsonRes.success).toBe(false);
- expect(jsonRes.message).toBe(NotValidJsonMsg);
- });
-
- test("not a valid json", async () => {
- const jsonRes = await parsePositionalFile("tests/fixtures/bad.json");
- expect(jsonRes.success).toBe(false);
- expect(jsonRes.message).toBe(NotValidJsonMsg);
- });
-
- test("valid json", async () => {
- const jsonRes = await parsePositionalFile("tests//fixtures/valid.json");
- expect(jsonRes.success).toBe(true);
- expect(jsonRes.body).toHaveProperty("HELLO", { type: "string" } );
- expect(jsonRes.body).toHaveProperty("HELLO3", { type: "string" } );
- expect(jsonRes.body).toHaveProperty("HELLO_3", { type: "string" });
- });
-});
diff --git a/util/config/configurator/tsconfig.json
b/util/config/configurator/tsconfig.json
deleted file mode 100644
index 238655f..0000000
--- a/util/config/configurator/tsconfig.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "compilerOptions": {
- // Enable latest features
- "lib": ["ESNext", "DOM"],
- "target": "ESNext",
- "module": "ESNext",
- "moduleDetection": "force",
- "jsx": "react-jsx",
- "allowJs": true,
-
- // Bundler mode
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "verbatimModuleSyntax": true,
- "noEmit": true,
-
- // Best practices
- "strict": true,
- "skipLibCheck": true,
- "noFallthroughCasesInSwitch": true,
-
- // Some stricter flags (disabled by default)
- "noUnusedLocals": false,
- "noUnusedParameters": false,
- "noPropertyAccessFromIndexSignature": false
- }
-}