"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/config/format.ts var format_exports = {}; __export(format_exports, { NormalizationError: () => NormalizationError, assertValidConfig: () => assertValidConfig, getInvalidConfigReason: () => getInvalidConfigReason, isValidConfig: () => isValidConfig, normalize: () => normalize, override: () => override }); module.exports = __toCommonJS(format_exports); var import_errors = require("../utils/errors"); var import_objects = require("../utils/objects"); function isValidConfig(c) { return getInvalidConfigReason(c) === void 0; } function getInvalidConfigReason(c, options = {}) { const configName = options.configName ?? "config"; if (c === null || typeof c !== "object") return `${configName} must be a non-null object`; for (const [key, value] of Object.entries(c)) { if (value === void 0) continue; if (typeof key !== "string") return `${configName} must have only string keys (found: ${typeof key})`; if (!key.match(/^[a-zA-Z0-9_:$][a-zA-Z_:$0-9\-]*(?:\.[a-zA-Z0-9_:$][a-zA-Z_:$0-9\-]*)*$/)) return `All keys of ${configName} must consist of only alphanumeric characters, dots, underscores, colons, dollar signs, or hyphens and start with a character other than a hyphen (found: ${key})`; const entryName = `${configName}.${key}`; const reason = getInvalidConfigValueReason(value, { valueName: entryName }); if (reason) return reason; } return void 0; } function getInvalidConfigValueReason(value, options = {}) { const valueName = options.valueName ?? "value"; switch (typeof value) { case "string": case "number": case "boolean": { break; } case "object": { if (value === null) { break; } else if (Array.isArray(value)) { for (const [index, v] of value.entries()) { const reason = getInvalidConfigValueReason(v, { valueName: `${valueName}[${index}]` }); if (reason) return reason; } } else { const reason = getInvalidConfigReason(value, { configName: valueName }); if (reason) return reason; } break; } default: { return `${valueName} has an invalid value type ${typeof value} (value: ${value})`; } } return void 0; } function assertValidConfig(c) { const reason = getInvalidConfigReason(c); if (reason) throw new import_errors.StackAssertionError(`Invalid config: ${reason}`, { c }); } function override(c1, ...configs) { if (configs.length === 0) return c1; if (configs.length > 1) return override(override(c1, configs[0]), ...configs.slice(1)); const c2 = configs[0]; assertValidConfig(c1); assertValidConfig(c2); let result = c1; for (const key of Object.keys((0, import_objects.filterUndefined)(c2))) { result = Object.fromEntries( Object.entries(result).filter(([k]) => k !== key && !k.startsWith(key + ".")) ); } return { ...result, ...(0, import_objects.filterUndefined)(c2) }; } var NormalizationError = class extends Error { constructor(...args) { super(...args); } }; NormalizationError.prototype.name = "NormalizationError"; function normalize(c, options = {}) { assertValidConfig(c); const onDotIntoNull = options.onDotIntoNull ?? "empty"; const countDots = (s) => s.match(/\./g)?.length ?? 0; const result = {}; const keysByDepth = Object.keys(c).sort((a, b) => countDots(a) - countDots(b)); outer: for (const key of keysByDepth) { const keySegmentsWithoutLast = key.split("."); const last = keySegmentsWithoutLast.pop() ?? (0, import_errors.throwErr)("split returns empty array?"); const value = (0, import_objects.get)(c, key); if (value === void 0) continue; let current = result; for (const keySegment of keySegmentsWithoutLast) { if (!(0, import_objects.hasAndNotUndefined)(current, keySegment)) { switch (onDotIntoNull) { case "empty": { (0, import_objects.set)(current, keySegment, {}); break; } case "throw": { throw new NormalizationError(`Tried to use dot notation to access ${JSON.stringify(key)}, but ${JSON.stringify(keySegment)} doesn't exist on the object (or is null). Maybe this config is not normalizable?`); } case "ignore": { continue outer; } } } const value2 = (0, import_objects.get)(current, keySegment); if (typeof value2 !== "object") { throw new NormalizationError(`Tried to use dot notation to access ${JSON.stringify(key)}, but ${JSON.stringify(keySegment)} is not an object. Maybe this config is not normalizable?`); } current = value2; } setNormalizedValue(current, last, value); } return result; } function normalizeValue(value) { if (value === null) throw new NormalizationError("Tried to normalize a null value"); if (Array.isArray(value)) return value.map(normalizeValue); if (typeof value === "object") return normalize(value); return value; } function setNormalizedValue(result, key, value) { if (value === null) { if ((0, import_objects.hasAndNotUndefined)(result, key)) { (0, import_objects.deleteKey)(result, key); } } else { (0, import_objects.set)(result, key, normalizeValue(value)); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { NormalizationError, assertValidConfig, getInvalidConfigReason, isValidConfig, normalize, override }); //# sourceMappingURL=format.js.map