+ /**
+ * Returns the property descriptor for the own property with the
+ * provided property key on the provided object, or null if none
+ * exists.
+ *
+ * ※ This is an alias for Object.getOwnPropertyDescriptor.
+ */
+ getOwnPropertyDescriptor,
+
+ /**
+ * Returns the property descriptors for the own properties on the
+ * provided object.
+ *
+ * ※ This is an alias for Object.getOwnPropertyDescriptors.
+ */
+ getOwnPropertyDescriptors,
+
+ /**
+ * Returns an array of string‐valued own property keys on the
+ * provided object.
+ *
+ * ☡ This includes both enumerable and non·enumerable properties.
+ *
+ * ※ This is an alias for Object.getOwnPropertyNames.
+ */
+ getOwnPropertyNames: getOwnPropertyStrings,
+
+ /**
+ * Returns an array of symbol‐valued own property keys on the
+ * provided object.
+ *
+ * ☡ This includes both enumerable and non·enumerable properties.
+ *
+ * ※ This is an alias for Object.getOwnPropertySymbols.
+ */
+ getOwnPropertySymbols,
+
+ /**
+ * Returns the prototype of the provided object.
+ *
+ * ※ This is an alias for Object.getPrototypeOf.
+ */
+ getPrototypeOf: getPrototype,
+
+ /**
+ * Returns whether the provided object has an own property with the
+ * provided property key.
+ *
+ * ※ This is an alias for Object.hasOwn.
+ */
+ hasOwn: hasOwnProperty,
+
+ /**
+ * Returns whether the provided object is extensible.
+ *
+ * ※ This is an alias for Object.isExtensible.
+ */
+ isExtensible,
+
+ /**
+ * Returns whether the provided object is frozen.
+ *
+ * ※ This is an alias for Object.isFrozen.
+ */
+ isFrozen,
+
+ /**
+ * Returns whether the provided object is sealed.
+ *
+ * ※ This is an alias for Object.isSealed.
+ */
+ isSealed,
+
+ /**
+ * Returns an array of key~value pairs for the enumerable,
+ * string‐valued property keys on the provided object.
+ *
+ * ※ This is an alias for Object.entries.
+ */
+ entries: namedEntries,
+
+ /**
+ * Returns an array of the enumerable, string‐valued property keys on
+ * the provided object.
+ *
+ * ※ This is an alias for Object.keys.
+ */
+ keys: namedKeys,
+
+ /**
+ * Returns an array of property values for the enumerable,
+ * string‐valued property keys on the provided object.
+ *
+ * ※ This is an alias for Object.values.
+ */
+ values: namedValues,
+
+ /**
+ * Returns a new object with the provided prototype and property
+ * descriptors.
+ *
+ * ※ This is an alias for Object.create.
+ */
+ create: objectCreate,
+
+ /**
+ * Returns a new object with the provided property keys and values.
+ *
+ * ※ This is an alias for Object.fromEntries.
+ */
+ fromEntries: objectFromEntries,
+
+ /**
+ * Marks the provided object as non·extensible, and returns the
+ * object.
+ *
+ * ※ This is an alias for Object.preventExtensions.
+ */
+ preventExtensions,
+
+ /**
+ * Marks the provided object as non·extensible and marks all its
+ * properties as nonconfigurable, and returns the object.
+ *
+ * ※ This is an alias for Object.seal.
+ */
+ seal,
+
+ /**
+ * Sets the values of the enumerable own properties of the provided
+ * additional objects on the provided object.
+ *
+ * ※ This is an alias for Object.assign.
+ */
+ assign: setPropertyValues,
+
+ /**
+ * Sets the prototype of the provided object to the provided value
+ * and returns the object.
+ *
+ * ※ This is an alias for Object.setPrototypeOf.
+ */
+ setPrototypeOf: setPrototype,
+} = Object;
+
+export const {
+ /**
+ * Removes the provided property key from the provided object and
+ * returns the object.
+ *
+ * ※ This function differs from Reflect.deleteProperty and the
+ * `delete` operator in that it throws if the deletion is
+ * unsuccessful.
+ *
+ * ☡ This function throws if the first argument is not an object.
+ */
+ deleteOwnProperty,
+
+ /**
+ * Returns an array of property keys on the provided object.
+ *
+ * ※ This is effectively an alias for Reflect.ownKeys, except that
+ * it does not require that the argument be an object.
+ */
+ getOwnPropertyKeys,
+
+ /**
+ * Returns the value of the provided property key on the provided
+ * object.
+ *
+ * ※ This is effectively an alias for Reflect.get, except that it
+ * does not require that the argument be an object.
+ */
+ getPropertyValue,
+
+ /**
+ * Returns whether the provided property key exists on the provided
+ * object.
+ *
+ * ※ This is effectively an alias for Reflect.has, except that it
+ * does not require that the argument be an object.
+ *
+ * ※ This includes properties present on the prototype chain.
+ */
+ hasProperty,
+
+ /**
+ * Sets the provided property key to the provided value on the
+ * provided object and returns the object.
+ *
+ * ※ This function differs from Reflect.set in that it throws if the
+ * setting is unsuccessful.
+ *
+ * ☡ This function throws if the first argument is not an object.
+ */
+ setPropertyValue,
+} = (() => {
+ const { deleteProperty, get, has, ownKeys, set } = Reflect;
+
+ return {
+ deleteOwnProperty: (O, P) => {
+ if (type(O) !== "object") {
+ throw new TypeError(
+ `Piscēs: Tried to set property but provided value was not an object: ${V}`,
+ );
+ } else if (!deleteProperty(O, P)) {
+ throw new TypeError(
+ `Piscēs: Tried to delete property from object but [[Delete]] returned false: ${P}`,
+ );
+ } else {
+ return O;
+ }
+ },
+ getOwnPropertyKeys: (O) => ownKeys(toObject(O)),
+ getPropertyValue: (O, P, Receiver = O) =>
+ get(toObject(O), P, Receiver),
+ hasProperty: (O, P) => has(toObject(O), P),
+ setPropertyValue: (O, P, V, Receiver = O) => {
+ if (type(O) !== "object") {
+ throw new TypeError(
+ `Piscēs: Tried to set property but provided value was not an object: ${V}`,
+ );
+ } else if (!set(O, P, V, Receiver)) {
+ throw new TypeError(
+ `Piscēs: Tried to set property on object but [[Set]] returned false: ${P}`,
+ );
+ } else {
+ return O;
+ }
+ },
+ };
+})();
+
+export const {
+ /**
+ * Returns a new frozen shallow copy of the enumerable own properties
+ * of the provided object, according to the following rules :—
+ *
+ * - For data properties, create a nonconfigurable, nonwritable
+ * property with the same value.
+ *
+ * - For accessor properties, create a nonconfigurable accessor
+ * property with the same getter *and* setter.
+ *
+ * The prototype for the resulting object will be taken from the
+ * `prototype` property of the provided constructor, or the
+ * `prototype` of the `constructor` of the provided object if the
+ * provided constructor is undefined. If the used constructor has a
+ * nonnullish `Symbol.species`, that will be used instead. If the
+ * used constructor or species is nullish or does not have a
+ * `prototype` property, the prototype is set to null.
+ *
+ * ※ The prototype of the provided object itself is ignored.
+ */
+ frozenCopy,
+} = (() => {
+ const {
+ iterator: iteratorSymbol,
+ species: speciesSymbol,
+ } = Symbol;
+ const {
+ next: generatorIteratorNext,
+ } = getPrototype(function* () {}.prototype);
+ const propertyDescriptorEntryIterablePrototype = {
+ [iteratorSymbol]() {
+ return {
+ next: bind(generatorIteratorNext, this.generator(), []),
+ };
+ },
+ };
+ return {
+ frozenCopy: (O, constructor = O?.constructor) => {
+ if (O == null) {
+ // O is null or undefined.
+ throw new TypeError(
+ "Piscēs: Cannot copy properties of null or undefined.",
+ );
+ } else {
+ // O is not null or undefined.
+ //
+ // (If not provided, the constructor will be the value of
+ // getting the `constructor` property of O.)
+ const species = constructor?.[speciesSymbol] ?? constructor;
+ return preventExtensions(
+ objectCreate(
+ species == null || !("prototype" in species)
+ ? null
+ : species.prototype,
+ objectFromEntries(
+ objectCreate(
+ propertyDescriptorEntryIterablePrototype,
+ {
+ generator: {
+ value: function* () {
+ const ownPropertyKeys = getOwnPropertyKeys(O);
+ for (
+ let i = 0;
+ i < ownPropertyKeys.length;
+ ++i
+ ) {
+ const P = ownPropertyKeys[i];
+ const Desc = getOwnPropertyDescriptor(O, P);
+ if (Desc.enumerable) {
+ // P is an enumerable property.
+ yield [
+ P,
+ "get" in Desc || "set" in Desc
+ ? {
+ configurable: false,
+ enumerable: true,
+ get: Desc.get,
+ set: Desc.set,
+ }
+ : {
+ configurable: false,
+ enumerable: true,
+ value: Desc.value,
+ writable: false,
+ },
+ ];
+ } else {
+ // P is not an enumerable property.
+ /* do nothing */
+ }
+ }
+ },
+ },
+ },
+ ),
+ ),
+ ),
+ );
+ }
+ },
+ };
+})();