Bin
2025-12-16 9e0b2ba2c317b1a86212f24cbae3195ad1f3dbfa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { getParent, getType, isRoot, types } from "mobx-state-tree";
 
import Registry from "./Registry";
import { ConfigurationError } from "../utils/errors";
 
function _mixedArray(fn) {
  return (arr) => types.maybeNull(types.array(fn(arr)));
}
 
function _oneOf(lookup, err) {
  return (arr) =>
    types.union({
      dispatcher: (sn) => {
        if (arr.find((val) => sn.type === val)) {
          return lookup(sn.type);
        }
        throw new ConfigurationError(err + sn.type);
      },
    });
}
 
const oneOfTags = _oneOf(Registry.getModelByTag, "Not expecting tag: ");
const tagsArray = _mixedArray(oneOfTags);
 
function unionArray(arr) {
  const type = types.maybeNull(types.array(oneOfTags(arr)));
 
  type.value = arr;
  return type;
}
 
function unionTag(arr) {
  return types.maybeNull(types.enumeration("unionTag", arr));
}
 
function tagsTypes(arr) {
  const type = types.frozen(arr.map((val) => val.toLowerCase()));
 
  type.describe = () => `(${arr.join("|")})`;
  type.value = arr;
  return type;
}
 
function allModelsTypes() {
  const args = [
    {
      dispatcher: (sn) => {
        if (!sn) return types.literal(undefined);
        if (Registry.tags.includes(sn.type)) {
          return Registry.getModelByTag(sn.type);
        }
        throw new ConfigurationError(`Not expecting tag: ${sn.type}`);
      },
    },
    Registry.modelsArr(),
  ];
 
  const results = [].concat.apply([], args);
 
  return types.union.apply(null, results);
}
 
function isType(node, types) {
  const nt = getType(node);
 
  for (const t of types) if (nt === t) return true;
 
  return false;
}
 
function getParentOfTypeString(node, str) {
  if (isRoot(node)) return null;
 
  // same as getParentOfType but checks models .name instead of type
  let parent = getParent(node);
 
  if (!Array.isArray(str)) str = [str];
 
  while (parent) {
    const name = getType(parent).name;
 
    if (str.find((c) => c === name)) return parent;
 
    parent = isRoot(parent) ? null : getParent(parent);
  }
 
  return null;
}
 
function getParentTagOfTypeString(node, str) {
  // same as getParentOfType but checks models .name instead of type
  let parent = getParent(node);
 
  if (!Array.isArray(str)) str = [str];
 
  while (parent) {
    const parentType = parent.type;
 
    if (str.find((c) => c === parentType)) return parent;
 
    parent = isRoot(parent) ? null : getParent(parent);
  }
 
  return null;
}
 
const oneOfTools = _oneOf(Registry.getTool, "Not expecting tool: ");
const toolsArray = _mixedArray(oneOfTools);
 
const Types = {
  unionArray,
  allModelsTypes,
  unionTag,
  tagsTypes,
  isType,
  getParentOfTypeString,
  getParentTagOfTypeString,
  tagsArray,
  toolsArray,
};
 
export default Types;