import { redactString } from './chunk-UWUBFNLX.js';
import { __name } from './chunk-IBAHCH6O.js';

// src/lib/detect-runtime.ts
var versionsStr = "versions";
var processVersions = typeof process !== "undefined" && process[versionsStr];
processVersions && processVersions.node != null;
typeof window !== "undefined" && window.name === "nodejs" || typeof navigator !== "undefined" && "userAgent" in navigator && typeof navigator.userAgent === "string" && (navigator.userAgent.includes("Node.js") || navigator.userAgent.includes("jsdom"));
typeof Deno !== "undefined" && typeof Deno.version !== "undefined" && typeof Deno.version.deno !== "undefined";
processVersions && processVersions.bun != null;
var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement === "function" && typeof navigator !== "undefined" && typeof navigator.userAgent === "string";

// src/runtime/lib/debug.ts
function debug(...args) {
  if (!globalThis.process?.env.DEBUG_VARLOCK) return;
  console.log(...args);
}
__name(debug, "debug");

// src/runtime/env.ts
function isString(s) {
  return Object.prototype.toString.call(s) === "[object String]";
}
__name(isString, "isString");
var UNMASK_STR = "\u{1F441}";
var REDACTION_STATE_KEY = "__varlockRedactionState";
function getRedactionState() {
  if (!globalThis[REDACTION_STATE_KEY]) {
    globalThis[REDACTION_STATE_KEY] = {
      sensitiveSecretsMap: {},
      redactorFindReplace: void 0
    };
  }
  return globalThis[REDACTION_STATE_KEY];
}
__name(getRedactionState, "getRedactionState");
function resetRedactionMap(graph) {
  const state = getRedactionState();
  state.sensitiveSecretsMap = {};
  for (const itemKey in graph.config) {
    const item = graph.config[itemKey];
    if (item.isSensitive && item.value && isString(item.value)) {
      const redacted = redactString(item.value);
      if (redacted) {
        state.sensitiveSecretsMap[item.value] = {
          key: itemKey,
          redacted,
          preventLeaks: item.preventLeaks !== false
        };
      }
    }
  }
  if (!Object.keys(state.sensitiveSecretsMap).length) {
    state.redactorFindReplace = void 0;
    return;
  }
  const findRegex = new RegExp(
    [
      `(${UNMASK_STR} )?`,
      "(",
      Object.keys(state.sensitiveSecretsMap).map((s) => s.replace(/[()[\]{}*+?^$|#.,/\\\s-]/g, "\\$&")).sort((a, b) => b.length - a.length).join("|"),
      ")",
      `( ${UNMASK_STR})?`
    ].join(""),
    "g"
  );
  const replaceFn = /* @__PURE__ */ __name((match, pre, val, post) => {
    if (pre && post) return match;
    return state.sensitiveSecretsMap[val].redacted;
  }, "replaceFn");
  state.redactorFindReplace = { find: findRegex, replace: replaceFn };
}
__name(resetRedactionMap, "resetRedactionMap");
function getRedactionHoldbackLength(str) {
  const { sensitiveSecretsMap } = getRedactionState();
  const sensitiveValues = Object.keys(sensitiveSecretsMap);
  if (!sensitiveValues.length || !str.length) return 0;
  let longestValueLength = 0;
  for (const v of sensitiveValues) {
    if (v.length > longestValueLength) longestValueLength = v.length;
  }
  const maxCheckLength = Math.min(str.length, longestValueLength - 1);
  for (let len = maxCheckLength; len > 0; len--) {
    const suffix = str.slice(str.length - len);
    for (const v of sensitiveValues) {
      if (v.length > len && v.startsWith(suffix)) return len;
    }
  }
  return 0;
}
__name(getRedactionHoldbackLength, "getRedactionHoldbackLength");
function getRedactionMapInfo() {
  const state = getRedactionState();
  return {
    sensitiveItemCount: Object.keys(state.sensitiveSecretsMap).length,
    hasRedactorRegex: !!state.redactorFindReplace
  };
}
__name(getRedactionMapInfo, "getRedactionMapInfo");
function redactSensitiveConfig(o) {
  const { redactorFindReplace } = getRedactionState();
  if (!redactorFindReplace) return o;
  if (!o) return o;
  if (Array.isArray(o)) {
    return o.map(redactSensitiveConfig);
  }
  if (o && typeof o === "object" && Object.getPrototypeOf(o) === Object.prototype) {
    try {
      return JSON.parse(redactSensitiveConfig(JSON.stringify(o)));
    } catch (err) {
      return o;
    }
  }
  const type = typeof o;
  if (type === "string" || type === "object" && Object.prototype.toString.call(o) === "[object String]") {
    return o.replaceAll(redactorFindReplace.find, redactorFindReplace.replace);
  }
  return o;
}
__name(redactSensitiveConfig, "redactSensitiveConfig");
function revealSensitiveConfig(secretStr) {
  if (!globalThis._varlockOrigWriteToConsoleFn) return secretStr;
  return `${UNMASK_STR} ${secretStr} ${UNMASK_STR}`;
}
__name(revealSensitiveConfig, "revealSensitiveConfig");
function scanForLeaks(toScan, meta) {
  debug("\u26A1\uFE0F varlock scanning for leaks");
  if (!toScan) return toScan;
  function scanStrForLeaks(strToScan) {
    const { sensitiveSecretsMap } = getRedactionState();
    for (const sensitiveValue in sensitiveSecretsMap) {
      if (!sensitiveSecretsMap[sensitiveValue].preventLeaks) continue;
      if (strToScan.includes(sensitiveValue)) {
        const itemKey = sensitiveSecretsMap[sensitiveValue].key;
        console.error([
          "",
          `\u{1F6A8} ${"DETECTED LEAKED SENSITIVE CONFIG"} \u{1F6A8}`,
          `> Config item key: ${itemKey}`,
          ...meta?.method ? [`> Scan method: ${meta.method}`] : [],
          ...meta?.file ? [`> File: ${meta.file}`] : [],
          ""
        ].join("\n"));
        throw new Error(`\u{1F6A8} DETECTED LEAKED SENSITIVE CONFIG - ${itemKey}`);
      }
    }
  }
  __name(scanStrForLeaks, "scanStrForLeaks");
  if (isString(toScan)) {
    scanStrForLeaks(toScan);
    return toScan;
  } else if (typeof Buffer !== "undefined" && toScan instanceof Buffer) {
    scanStrForLeaks(toScan.toString());
    return toScan;
  } else if (ArrayBuffer.isView(toScan) || toScan instanceof ArrayBuffer) {
    const decoder = new TextDecoder();
    scanStrForLeaks(decoder.decode(toScan));
    return toScan;
  } else if (toScan instanceof ReadableStream) {
    if (toScan.locked) {
      return toScan;
    }
    const chunkDecoder = new TextDecoder();
    return toScan.pipeThrough(
      new TransformStream({
        transform(chunk, controller) {
          const chunkStr = chunkDecoder.decode(chunk);
          scanStrForLeaks(chunkStr);
          controller.enqueue(chunk);
        }
      })
    );
  }
  return toScan;
}
__name(scanForLeaks, "scanForLeaks");
var initializedEnv = false;
var configHasErrors = false;
var envValues = {};
var varlockSettings = {};
var processExists = !!globalThis.process;
var originalProcessEnv = { ...processExists && process.env };
var varlockInjectedProcessEnvKeys;
function initVarlockEnv(opts) {
  debug("\u26A1\uFE0F INIT VARLOCK ENV!", initializedEnv, !!globalThis.__varlockLoadedEnv, !!globalThis.process?.env.__VARLOCK_ENV);
  if (isBrowser && !globalThis.process?.env.__VARLOCK_ENV) {
    initializedEnv = true;
    return;
  }
  let serializedEnvData;
  if (globalThis.__varlockLoadedEnv) {
    serializedEnvData = globalThis.__varlockLoadedEnv;
  } else if (processExists && process.env.__VARLOCK_ENV) {
    serializedEnvData = JSON.parse(process.env.__VARLOCK_ENV);
  } else {
    if (opts?.allowFail) return;
    console.error([
      "",
      "\u{1F6A8} initVarlockEnv failed  \u{1F6A8}",
      "try rerunning your command via `varlock run`",
      ""
    ].join("\n"));
    throw new Error("initVarlockEnv failed");
  }
  Object.assign(varlockSettings, serializedEnvData.settings);
  configHasErrors = !!serializedEnvData.errors;
  resetRedactionMap(serializedEnvData);
  const setProcessEnv = processExists && !serializedEnvData.settings?.disableProcessEnvInjection;
  if (setProcessEnv) {
    if (varlockInjectedProcessEnvKeys) {
      for (const key of varlockInjectedProcessEnvKeys) delete process.env[key];
      for (const key of Object.keys(originalProcessEnv)) process.env[key] = originalProcessEnv[key];
    }
    varlockInjectedProcessEnvKeys = [];
  }
  for (const itemKey in serializedEnvData.config) {
    const itemValue = serializedEnvData.config[itemKey].value;
    envValues[itemKey] = itemValue;
    if (setProcessEnv) {
      varlockInjectedProcessEnvKeys?.push(itemKey);
      process.env[itemKey] = itemValue === void 0 ? "" : String(itemValue);
    }
  }
  initializedEnv = true;
}
__name(initVarlockEnv, "initVarlockEnv");
try {
  if (!initializedEnv) {
    initVarlockEnv({ allowFail: true });
  }
} catch (err) {
}
var IGNORED_PROXY_KEYS = [
  // vue - see https://github.com/vuejs/core/blob/70773d00985135a50556c61fb9855ed6b930cb82/packages/reactivity/src/ref.ts#L101
  "__v_isRef"
];
var EnvProxy = new Proxy({}, {
  get(target, prop) {
    if (typeof prop === "symbol") return;
    if (IGNORED_PROXY_KEYS.includes(prop)) return;
    if (!initializedEnv) {
      throw new Error(
        "varlock ENV not initialized \u2014 make sure varlock is set up correctly.\nSee https://varlock.dev/docs/get-started for setup instructions."
      );
    }
    if (configHasErrors) {
      console.error(`[varlock] \u26A0\uFE0F ENV.${prop} accessed but config has errors \u2014 values may be missing or incorrect`);
      return void 0;
    }
    if (prop in envValues) return envValues[prop];
    if (globalThis.__varlockThrowOnMissingKeys) {
      if (globalThis.__varlockValidKeys && globalThis.__varlockValidKeys.includes(prop)) {
        throw new Error(`\`ENV.${prop}\` exists, but is not available in this environment`);
      } else {
        throw new Error(`\`ENV.${prop}\` does not exist`);
      }
    }
    return void 0;
  }
});
var ENV = EnvProxy;

export { ENV, debug, getRedactionHoldbackLength, getRedactionMapInfo, initVarlockEnv, redactSensitiveConfig, resetRedactionMap, revealSensitiveConfig, scanForLeaks, varlockSettings };
//# sourceMappingURL=chunk-PRASPAE4.js.map
//# sourceMappingURL=chunk-PRASPAE4.js.map