import '../../utils/types/array.js';
import { mapObj } from '../../utils/types/object.js';
import 'crypto';
import { isEqualToOrPrototypeOf } from '../../utils/inheritance.js';
import 'bs58';
import 'multiformats/bases/base58';
import 'varint';
import '../../utils/encoding/ss-58.js';
import TypedEnum from './typed-enum.js';
import TypedStruct from './typed-struct.js';
import '../../utils/types/iterable.js';
import '../../utils/types/set.js';
import 'blake2b';
import '../../utils/types/bytes.js';
import '../../utils/interfaces.js';
import '../../utils/assert.js';
import '../../utils/error.js';
import '../../utils/types/string.js';
import './with-base.js';
import './with-catch-null.js';
import './with-eq.js';
import './any-of.js';
import './with-from.js';
import './with-from-json-bytes.js';
import './typed-null.js';
import './create-placeholder.js';

/**
 * Extends supplied class which must be a successor of `TypedStruct`/`TypedEnum` by adding/overriding
 * its properties classes.
 *
 * @template C
 * @template K
 * @param {C} klass
 * @param {Object<string, K>} propertiesToOverride
 * @param {function(*, Object<string, K>): *} handleNested
 * @returns {C}
 */
function withProps(
  klass,
  propertiesToOverride,
  handleNested = withProps,
) {
  const fnName = `withProps(${klass.name}, ${JSON.stringify(
    mapObj(propertiesToOverride, ({ name }) => name),
  )})`;
  const isStruct = isEqualToOrPrototypeOf(TypedStruct, klass);
  const isEnum = isEqualToOrPrototypeOf(TypedEnum, klass);
  if (!isStruct && !isEnum) {
    throw new Error(`Unexpected class provided: \`${klass}\``);
  }

  if (isStruct) {
    const obj = {
      [fnName]: class extends klass {
        static Classes = {
          ...klass.Classes,
          ...propertiesToOverride,
        };
      },
    };

    return obj[fnName];
  } else {
    const obj = {
      [fnName]:
        klass.Class != null
          ? class extends klass {
            static Class = handleNested(klass.Class, propertiesToOverride);
          }
          : class extends klass {
            static Variants = klass.Variants.map((variant) => handleNested(variant, propertiesToOverride));
          },
    };

    return obj[fnName];
  }
}

export { withProps as default };
//# sourceMappingURL=with-props.js.map
