function proxyObject()

in packages/libs/datastore/src/mapping-tree/mapping-tree.ts [99:174]


function proxyObject<T extends object>(
  originalFileName: string,
  targetPointer: JsonPointer | JsonPath = "",
  value: any,
  mappings = new Array<PathMapping>(),
): MappingTreeItem<T> {
  const targetPointerPath = typeof targetPointer === "string" ? parseJsonPointer(targetPointer) : targetPointer;

  const instance: any = value;

  const push = (value: ProxyValue<any>) => {
    const filename = value.sourceFilename || originalFileName;
    if (!filename) {
      throw new Error("Assignment: filename must be specified when there is no default.");
    }

    const newPropertyPath = [...targetPointerPath, instance.length];
    const item = proxyDeepObject(originalFileName, newPropertyPath, value.value, mappings);
    instance.push(item);

    if (value.sourcePointer !== NoMapping) {
      tag(newPropertyPath, filename, parseJsonPointerForArray(value.sourcePointer), mappings);
    }

    return item;
  };

  const rewrite = (key: string, value: any) => {
    instance[key] = value;
  };

  const set = (key: string, value: ProxyValue<any>) => {
    // check if this is a correct assignment.
    if (value.value === undefined) {
      throw new Error(`Assignment: Value '${String(key)}' may not be undefined.`);
    }

    if (Object.prototype.hasOwnProperty.call(instance, key)) {
      throw new Exception(`Collision detected inserting into object: ${String(key)}`); //-- ${JSON.stringify(instance, null, 2)}
    }
    const filename = value.sourceFilename || originalFileName;
    if (!filename) {
      throw new Error("Assignment: filename must be specified when there is no default.");
    }

    const newPropertyPath = [...targetPointerPath, typeof key === "symbol" ? String(key) : key];
    instance[key] = proxyDeepObject(originalFileName, newPropertyPath, value.value, mappings);

    if (value.sourcePointer !== NoMapping) {
      tag(newPropertyPath, filename, parseJsonPointer(value.sourcePointer), mappings);
    }

    return true;
  };

  return new Proxy<MappingTreeItem<T>>(instance, {
    get(_: MappingTreeItem<T>, key: string | number | symbol): any {
      switch (key) {
        case "__push__":
          return push;
        case "__rewrite__":
          return rewrite;
        case "__set__":
          return set;
      }

      return instance[key];
    },

    set(_: MappingTreeItem<T>, key, value): boolean {
      throw new Error(
        `Use __set__ or __push__ to modify proxy graph. Trying to set ${String(key)} with value: ${value}`,
      );
    },
  });
}