text: // Copyright (c) Microsoft Corporation. All rights reserved.
  // Licensed under the MIT license.
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
      function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
      return new (P || (P = Promise))(function (resolve, reject) {
          function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
          function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
          function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
          step((generator = generator.apply(thisArg, _arguments || [])).next());
      });
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  const winreg = require("winreg");
  class RegistryKey {
      constructor(path) {
          if (!path) {
              throw new Error("Please provide a registry key path.");
          }
          const index = path.indexOf("\\");
          if (index <= 0) {
              throw new Error(`The registry key path is not valid: "${path}".`);
          }
          const hive = path.substring(0, index);
          const subpath = path.substring(index);
          this.winreg = new winreg({ hive: normalizeRegistryHive(hive), key: subpath });
      }
      get path() {
          return this.winreg.path;
      }
  }
  exports.RegistryKey = RegistryKey;
  class RegistryTypes {
  }
  exports.RegistryTypes = RegistryTypes;
  RegistryTypes.REG_BINARY = winreg.REG_BINARY;
  RegistryTypes.REG_DWORD = winreg.REG_DWORD;
  RegistryTypes.REG_EXPAND_SZ = winreg.REG_EXPAND_SZ;
  RegistryTypes.REG_MULTI_SZ = winreg.REG_MULTI_SZ;
  RegistryTypes.REG_NONE = winreg.REG_NONE;
  RegistryTypes.REG_QWORD = winreg.REG_QWORD;
  RegistryTypes.REG_SZ = winreg.REG_SZ;
  class RegistryValue {
      constructor(key, name, type, data) {
          this.key = key;
          this.name = name;
          this.type = type;
          this.data = data;
      }
      get isNumberType() {
          return isNumberType(this.type);
      }
      get isStringType() {
          return isStringType(this.type);
      }
  }
  exports.RegistryValue = RegistryValue;
  function addValue(key, value, type, data) {
      return __awaiter(this, void 0, void 0, function* () {
          return new Promise((resolve, reject) => {
              const onError = (err) => {
                  if (err) {
                      reject(new Error(`Unable to set registry value "${value}" to "${data}" (${type}) for key "${key.path}".\n${err}`));
                  }
                  else {
                      resolve();
                  }
              };
              try {
                  key.winreg.set(value, type, data, onError);
              }
              catch (err) {
                  onError(err);
              }
          });
      });
  }
  function addBooleanValue(key, value, data) {
      return __awaiter(this, void 0, void 0, function* () {
          return addValue(key, value, winreg.REG_DWORD, data ? "1" : "0");
      });
  }
  exports.addBooleanValue = addBooleanValue;
  function addNumberValue(key, value, data) {
      return __awaiter(this, void 0, void 0, function* () {
          return addValue(key, value, winreg.REG_DWORD, data.toString());
      });
  }
  exports.addNumberValue = addNumberValue;
  function addStringValue(key, value, data) {
      return __awaiter(this, void 0, void 0, function* () {
          return addValue(key, value, winreg.REG_SZ, data);
      });
  }
  exports.addStringValue = addStringValue;
  function deleteKey(key) {
      return __awaiter(this, void 0, void 0, function* () {
          return new Promise((resolve, reject) => {
              const onError = (err) => {
                  if (err) {
                      reject(new Error(`Unable to delete registry key "${key.path}".\n${err}`));
                  }
                  else {
                      resolve();
                  }
              };
              try {
                  key.winreg.keyExists((keyExistsError, exists) => {
                      if (exists) {
                          key.winreg.destroy(onError);
                      }
                      else {
                          onError(keyExistsError);
                      }
                  });
              }
              catch (err) {
                  onError(err);
              }
          });
      });
  }
  exports.deleteKey = deleteKey;
  function deleteValue(key, value) {
      return __awaiter(this, void 0, void 0, function* () {
          return new Promise((resolve, reject) => {
              const onError = (err) => {
                  if (err) {
                      reject(new Error(`Unable to delete registry value "${value}" in key "${key.path}".\n${err}`));
                  }
                  else {
                      resolve();
                  }
              };
              try {
                  key.winreg.valueExists(value, (valueExistsError, exists) => {
                      if (exists) {
                          key.winreg.remove(value, onError);
                      }
                      else {
                          onError(valueExistsError);
                      }
                  });
              }
              catch (err) {
                  onError(err);
              }
          });
      });
  }
  exports.deleteValue = deleteValue;
  function doesKeyExist(key) {
      return __awaiter(this, void 0, void 0, function* () {
          return new Promise((resolve, reject) => {
              const onError = (err, exists = false) => {
                  if (err) {
                      reject(new Error(`Unable to determine if registry key exists: "${key.path}".\n${err}`));
                  }
                  else {
                      resolve(exists);
                  }
              };
              try {
                  key.winreg.keyExists(onError);
              }
              catch (err) {
                  onError(err);
              }
          });
      });
  }
  exports.doesKeyExist = doesKeyExist;
  function doesValueExist(key, value) {
      return __awaiter(this, void 0, void 0, function* () {
          return new Promise((resolve, reject) => {
              const onError = (err, exists = false) => {
                  if (err) {
                      reject(new Error(`Unable to determine if registry value "${value}" exists for key "${key.path}".\n${err}`));
                  }
                  else {
                      resolve(exists);
                  }
              };
              try {
                  key.winreg.valueExists(value, onError);
              }
              catch (err) {
                  onError(err);
              }
          });
      });
  }
  exports.doesValueExist = doesValueExist;
  function getNumberValue(key, value) {
      return __awaiter(this, void 0, void 0, function* () {
          const registryValue = yield getValue(key, value);
          return (registryValue && registryValue.isNumberType) ? parseInt(registryValue.data, undefined) : undefined;
      });
  }
  exports.getNumberValue = getNumberValue;
  function getStringValue(key, value) {
      return __awaiter(this, void 0, void 0, function* () {
          const registryValue = yield getValue(key, value);
          return (registryValue && registryValue.isStringType) ? registryValue.data : undefined;
      });
  }
  exports.getStringValue = getStringValue;
  function getValue(key, value) {
      return __awaiter(this, void 0, void 0, function* () {
          return new Promise((resolve, reject) => {
              const onError = (err, item) => {
                  if (err) {
                      resolve(undefined);
                  }
                  else {
                      resolve(item ? new RegistryValue(key.path, item.name, item.type, item.value) : undefined);
                  }
              };
              try {
                  key.winreg.get(value, onError);
              }
              catch (err) {
                  onError(err);
              }
          });
      });
  }
  exports.getValue = getValue;
  function getValues(key) {
      return __awaiter(this, void 0, void 0, function* () {
          return new Promise((resolve, reject) => {
              const callback = (err, items) => {
                  if (err) {
                      reject(err);
                  }
                  else {
                      resolve(items.map(item => new RegistryValue(key.path, item.name, item.type, item.value)));
                  }
              };
              try {
                  key.winreg.values(callback);
              }
              catch (err) {
                  reject(err);
              }
          });
      });
  }
  exports.getValues = getValues;
  function isNumberType(registryType) {
      // NOTE: REG_QWORD is not included as a number type since it cannot be returned as a "number".
      return (registryType === RegistryTypes.REG_DWORD);
  }
  exports.isNumberType = isNumberType;
  function isStringType(registryType) {
      switch (registryType) {
          case RegistryTypes.REG_SZ:
              return true;
          default:
              return false;
      }
  }
  exports.isStringType = isStringType;
  function normalizeRegistryHive(hive) {
      switch (hive) {
          case "HKEY_CURRENT_USER":
              return winreg.HKCU;
          case "HKEY_LOCAL_MACHINE":
              return winreg.HKLM;
          case "HKEY_CLASSES_ROOT":
              return winreg.HKCR;
          case "HKEY_CURRENT_CONFIG":
              return winreg.HKCC;
          case "HKEY_USERS":
              return winreg.HKU;
          default:
              return hive;
      }
  }
  //# sourceMappingURL=registry.js.map