@blitznocode/blitz-orm 0.0.43 → 0.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -66,19 +66,21 @@ type BormRelation = BormEntity & {
66
66
  [key: string]: RoleField;
67
67
  };
68
68
  };
69
- type EnrichedBormEntity = Omit<BormEntity, 'linkFields' | 'idFields'> & {
69
+ type EnrichedBormEntity = Omit<BormEntity, 'linkFields' | 'idFields' | 'dataFields'> & {
70
70
  extends?: string;
71
71
  idFields: string[];
72
72
  thingType: 'entity';
73
73
  name: string;
74
74
  computedFields: string[];
75
75
  linkFields?: EnrichedLinkField[];
76
+ dataFields?: EnrichedDataField[];
76
77
  };
77
- type EnrichedBormRelation = Omit<BormRelation, 'linkFields'> & {
78
+ type EnrichedBormRelation = Omit<BormRelation, 'linkFields' | 'dataFields'> & {
78
79
  thingType: 'relation';
79
80
  name: string;
80
81
  computedFields: string[];
81
82
  linkFields?: EnrichedLinkField[];
83
+ dataFields?: EnrichedDataField[];
82
84
  roles: {
83
85
  [key: string]: EnrichedRoleField;
84
86
  };
@@ -147,6 +149,9 @@ type DataField = BormField & {
147
149
  validations?: any;
148
150
  dbConnectors?: [DBConnector, ...DBConnector[]];
149
151
  };
152
+ type EnrichedDataField = DataField & {
153
+ dbPath: string;
154
+ };
150
155
  type ThingType = 'entity' | 'relation' | 'attribute';
151
156
  type RightType = 'CREATE' | 'DELETE' | 'UPDATE' | 'LINK' | 'UNLINK';
152
157
  type ContentType = 'ID' | 'JSON' | 'COLOR' | 'BOOLEAN' | 'POINT' | 'FILE' | 'EMAIL' | 'PHONE' | 'WEEK_DAY' | 'DURATION' | 'HOUR' | 'TIME' | 'DATE' | 'RATING' | 'CURRENCY' | 'PERCENTAGE' | 'NUMBER_DECIMAL' | 'NUMBER' | 'URL' | 'PASSWORD' | 'LANGUAGE_TEXT' | 'RICH_TEXT' | 'TEXT';
@@ -247,4 +252,4 @@ declare class BormClient {
247
252
  close: () => Promise<void>;
248
253
  }
249
254
 
250
- export { BQLField, BQLFieldObj, BQLMutationBlock, BQLResponse, BQLResponseMulti, BQLResponseSingle, BormConfig, BormEntity, BormField, BormRelation, BormSchema, CardinalityType, ContentType, DBConnector, DBHandles, DataField, DataFilter, EnrichedBormEntity, EnrichedBormRelation, EnrichedBormSchema, EnrichedLinkField, EnrichedRoleField, FilledBQLMutationBlock, Filter, LinkField, LinkFilter, LinkedFieldWithThing, MiddleFilter, ParsedBQLMutation, ParsedBQLQuery, ProviderObject, RawBQLMutation, RawBQLQuery, RelationClassType, RightType, RoleField, TQLEntityMutation, TQLRequest, ThingType, BormClient as default };
255
+ export { BQLField, BQLFieldObj, BQLMutationBlock, BQLResponse, BQLResponseMulti, BQLResponseSingle, BormConfig, BormEntity, BormField, BormRelation, BormSchema, CardinalityType, ContentType, DBConnector, DBHandles, DataField, DataFilter, EnrichedBormEntity, EnrichedBormRelation, EnrichedBormSchema, EnrichedDataField, EnrichedLinkField, EnrichedRoleField, FilledBQLMutationBlock, Filter, LinkField, LinkFilter, LinkedFieldWithThing, MiddleFilter, ParsedBQLMutation, ParsedBQLQuery, ProviderObject, RawBQLMutation, RawBQLQuery, RelationClassType, RightType, RoleField, TQLEntityMutation, TQLRequest, ThingType, BormClient as default };
package/dist/index.js CHANGED
@@ -44,9 +44,12 @@ var defaultConfig = {
44
44
  var import_immer = __toESM(require("immer"));
45
45
  var import_object_traversal = require("object-traversal");
46
46
  var import_radash = require("radash");
47
- var oFind = (obj, fn) => Object.values(
48
- Object.fromEntries(Object.entries(obj).filter(([k, v]) => fn(k, v)))
49
- )[0];
47
+ var getDbPath = (thing, attribute, shared) => shared ? attribute : `${thing}\xB7${attribute}`;
48
+ var getPath = (dbPath) => {
49
+ const parts = dbPath.split("\xB7");
50
+ return parts[parts.length - 1];
51
+ };
52
+ var oFind = (obj, fn) => Object.values(Object.fromEntries(Object.entries(obj).filter(([k, v]) => fn(k, v))))[0];
50
53
  var oFilter = (obj, fn) => Object.fromEntries(Object.entries(obj).filter(([k, v]) => fn(k, v)));
51
54
  var enrichSchema = (schema) => {
52
55
  const allLinkedFields = [];
@@ -54,12 +57,34 @@ var enrichSchema = (schema) => {
54
57
  schema,
55
58
  (draft) => (0, import_object_traversal.traverse)(
56
59
  draft,
57
- ({ value, meta }) => {
58
- if (meta.depth === 2 && value.extends) {
60
+ ({ key, value, meta }) => {
61
+ if (meta.depth !== 2) {
62
+ return;
63
+ }
64
+ if (key) {
65
+ value.dataFields = value.dataFields?.map((df) => ({
66
+ ...df,
67
+ dbPath: getDbPath(key, df.path, df.shared)
68
+ }));
69
+ }
70
+ if (value.extends) {
59
71
  const extendedSchema = draft.entities[value.extends] || draft.relations[value.extends];
60
72
  value;
61
73
  value.idFields = extendedSchema.idFields ? (value.idFields || []).concat(extendedSchema.idFields) : value.idFields;
62
- value.dataFields = extendedSchema.dataFields ? (value.dataFields || []).concat(extendedSchema.dataFields) : value.dataFields;
74
+ value.dataFields = extendedSchema.dataFields ? (value.dataFields || []).concat(
75
+ extendedSchema.dataFields.map((df) => {
76
+ let deepExtendedThing = value.extends;
77
+ let deepSchema = schema.entities[deepExtendedThing] || schema.relations[deepExtendedThing];
78
+ while (!deepSchema.dataFields?.find((deepDf) => deepDf.path === df.path)) {
79
+ deepExtendedThing = deepSchema.extends;
80
+ deepSchema = schema.entities[deepExtendedThing] || schema.relations[deepExtendedThing];
81
+ }
82
+ return {
83
+ ...df,
84
+ dbPath: getDbPath(deepExtendedThing, df.path, df.shared)
85
+ };
86
+ })
87
+ ) : value.dataFields;
63
88
  value.linkFields = extendedSchema.linkFields ? (value.linkFields || []).concat(extendedSchema.linkFields) : value.linkFields;
64
89
  if ("roles" in extendedSchema) {
65
90
  const val = value;
@@ -84,9 +109,7 @@ var enrichSchema = (schema) => {
84
109
  if (!meta.nodePath) {
85
110
  throw new Error("No path");
86
111
  }
87
- const pathArray = meta.nodePath.split(".");
88
- const thingPath = pathArray[0];
89
- const thing = pathArray[1];
112
+ const [thingPath, thing] = meta.nodePath.split(".");
90
113
  const thingType = thingPath === "entities" ? "entity" : thingPath === "relations" ? "relation" : "";
91
114
  return {
92
115
  thing,
@@ -120,9 +143,7 @@ var enrichSchema = (schema) => {
120
143
  if ("roles" in value) {
121
144
  const val = value;
122
145
  Object.entries(val.roles).forEach(([roleKey, role]) => {
123
- role.playedBy = allLinkedFields.filter(
124
- (x) => x.relation === key && x.plays === roleKey
125
- ) || [];
146
+ role.playedBy = allLinkedFields.filter((x) => x.relation === key && x.plays === roleKey) || [];
126
147
  });
127
148
  }
128
149
  if ("linkFields" in value && value.linkFields) {
@@ -138,9 +159,7 @@ var enrichSchema = (schema) => {
138
159
  ];
139
160
  return;
140
161
  }
141
- const allOppositeLinkFields = allLinkedFields.filter(
142
- (x) => x.relation === linkField.relation && x.plays !== linkField.plays
143
- ) || [];
162
+ const allOppositeLinkFields = allLinkedFields.filter((x) => x.relation === linkField.relation && x.plays !== linkField.plays) || [];
144
163
  linkField.oppositeLinkFieldsPlayedBy = allOppositeLinkFields;
145
164
  const { filter } = linkField;
146
165
  linkField.oppositeLinkFieldsPlayedBy = linkField.oppositeLinkFieldsPlayedBy.filter(
@@ -166,11 +185,7 @@ var enrichSchema = (schema) => {
166
185
  }
167
186
  }
168
187
  if (typeof value === "object" && "playedBy" in value) {
169
- if ([
170
- ...new Set(
171
- value.playedBy?.map((x) => x.thing)
172
- )
173
- ].length > 1) {
188
+ if ([...new Set(value.playedBy?.map((x) => x.thing))].length > 1) {
174
189
  throw new Error(
175
190
  `Unsupported: roleFields can be only played by one thing. Role: ${key} path:${meta.nodePath}`
176
191
  );
@@ -240,22 +255,13 @@ var getCurrentFields = (currentSchema, node) => {
240
255
  return x.$path;
241
256
  throw new Error(" Wrongly structured query");
242
257
  }) : (0, import_radash.listify)(node, (k) => k);
243
- const localFilterFields = !node.$filter ? [] : (0, import_radash.listify)(
244
- node.$filter,
245
- (k) => k.toString().startsWith("$") ? void 0 : k.toString()
246
- ).filter((x) => x && availableDataFields?.includes(x));
247
- const nestedFilterFields = !node.$filter ? [] : (0, import_radash.listify)(
248
- node.$filter,
249
- (k) => k.toString().startsWith("$") ? void 0 : k.toString()
250
- ).filter(
251
- (x) => x && [
252
- ...availableRoleFields || [],
253
- ...availableLinkFields || []
254
- ]?.includes(x)
258
+ const localFilterFields = !node.$filter ? [] : (0, import_radash.listify)(node.$filter, (k) => k.toString().startsWith("$") ? void 0 : k.toString()).filter(
259
+ (x) => x && availableDataFields?.includes(x)
255
260
  );
256
- const unidentifiedFields = [...usedFields, ...localFilterFields].filter(
257
- (x) => !allowedFields.includes(x)
261
+ const nestedFilterFields = !node.$filter ? [] : (0, import_radash.listify)(node.$filter, (k) => k.toString().startsWith("$") ? void 0 : k.toString()).filter(
262
+ (x) => x && [...availableRoleFields || [], ...availableLinkFields || []]?.includes(x)
258
263
  );
264
+ const unidentifiedFields = [...usedFields, ...localFilterFields].filter((x) => !allowedFields.includes(x));
259
265
  const localFilters = !node.$filter ? {} : oFilter(node.$filter, (k, _v) => localFilterFields.includes(k));
260
266
  const nestedFilters = !node.$filter ? {} : oFilter(node.$filter, (k, _v) => nestedFilterFields.includes(k));
261
267
  return {
@@ -269,13 +275,9 @@ var getCurrentFields = (currentSchema, node) => {
269
275
  };
270
276
  };
271
277
  var getLocalFilters = (currentSchema, node) => {
272
- const thingPath = currentSchema.defaultDBConnector.path || currentSchema.name;
273
278
  const localFilters = node.$localFilters && (0, import_radash.listify)(node.$localFilters, (k, v) => {
274
- const currentDataField = currentSchema.dataFields?.find(
275
- (x) => x.path === k
276
- );
277
- const dbField = currentDataField?.shared ? k : `${thingPath}\xB7${k}`;
278
- return `has ${dbField} '${v}'`;
279
+ const currentDataField = currentSchema.dataFields?.find((x) => x.path === k);
280
+ return `has ${currentDataField?.dbPath} '${v}'`;
279
281
  });
280
282
  const localFiltersTql = localFilters?.length ? `, ${localFilters.join(",")}` : "";
281
283
  return localFiltersTql;
@@ -301,9 +303,7 @@ var extractEntities = (conceptMapGroups, schema) => {
301
303
  if (!attribute) {
302
304
  return [];
303
305
  }
304
- const nameParts = attribute.type.label.name.split("\xB7");
305
- const attributeName = nameParts[nameParts.length - 1];
306
- return [attributeName, attribute.value];
306
+ return [getPath(attribute.type.label.name), attribute.value];
307
307
  });
308
308
  const entity = Object.fromEntries(entityAttributes);
309
309
  return {
@@ -355,9 +355,7 @@ var parseTQLRes = async (req, res) => {
355
355
  const { query } = bqlRequest;
356
356
  if (!query) {
357
357
  if (rawTqlRes.insertions?.length === 0 && !tqlRequest?.deletions) {
358
- throw new Error(
359
- "Nothing has changed in DB, probably one of the ids specified in the mutation does not exist"
360
- );
358
+ throw new Error("Nothing has changed in DB, probably one of the ids specified in the mutation does not exist");
361
359
  }
362
360
  const { mutation } = bqlRequest;
363
361
  if (!mutation) {
@@ -365,14 +363,10 @@ var parseTQLRes = async (req, res) => {
365
363
  }
366
364
  const expected = [...mutation.things, ...mutation.edges];
367
365
  const result = expected.map((x) => {
368
- const currentNode = rawTqlRes.insertions?.[0].get(
369
- `${x.$tempId || x.$id}`
370
- );
366
+ const currentNode = rawTqlRes.insertions?.[0].get(`${x.$tempId || x.$id}`);
371
367
  if (x.$op === "create" || x.$op === "update" || x.$op === "link") {
372
368
  if (!currentNode?.asThing().iid) {
373
- throw new Error(
374
- `Thing not received on mutation: ${JSON.stringify(x)}`
375
- );
369
+ throw new Error(`Thing not received on mutation: ${JSON.stringify(x)}`);
376
370
  }
377
371
  const dbIdd = currentNode?.asThing().iid;
378
372
  if (config.mutation?.noMetadata) {
@@ -404,9 +398,7 @@ var parseTQLRes = async (req, res) => {
404
398
  currentRelSchema.roles,
405
399
  (_k, v) => {
406
400
  if ([...new Set(v.playedBy?.map((x) => x.thing))].length !== 1) {
407
- throw new Error(
408
- "a role can be played by two entities throws the same relation"
409
- );
401
+ throw new Error("a role can be played by two entities throws the same relation");
410
402
  }
411
403
  if (!v.playedBy)
412
404
  throw new Error("Role not being played by nobody");
@@ -541,9 +533,7 @@ var filterChildrenEntities = (things, ids, node, path) => things.map(([id, entit
541
533
  return id;
542
534
  if (node.$fields.includes(path))
543
535
  return id;
544
- const currentFieldConf = node.$fields.find(
545
- (f) => (0, import_radash4.isObject)(f) && f.$path === path
546
- );
536
+ const currentFieldConf = node.$fields.find((f) => (0, import_radash4.isObject)(f) && f.$path === path);
547
537
  if (currentFieldConf) {
548
538
  const onlyMetadataEntity = {
549
539
  ...oFilter(entity, (k, _v) => k.startsWith("$"))
@@ -638,12 +628,7 @@ var buildBQLTree = async (req, res) => {
638
628
  const thingEntities = cache.entities.get(x);
639
629
  if (!thingEntities)
640
630
  return [];
641
- return filterChildrenEntities(
642
- [...thingEntities],
643
- uniqueLinkedIds,
644
- value,
645
- rolePath
646
- );
631
+ return filterChildrenEntities([...thingEntities], uniqueLinkedIds, value, rolePath);
647
632
  });
648
633
  if (children?.length) {
649
634
  if (children.length === 1 && children[0] === value.$id) {
@@ -667,15 +652,11 @@ var buildBQLTree = async (req, res) => {
667
652
  const tunnel = linkField.oppositeLinkFieldsPlayedBy;
668
653
  if (linkField.target === "relation") {
669
654
  const targetRelation = tunnel[0];
670
- const targetRelationThings = cache.relations.get(
671
- linkField.relation
672
- );
655
+ const targetRelationThings = cache.relations.get(linkField.relation);
673
656
  const matchedLinks = !targetRelationThings ? [] : [...targetRelationThings].filter((link) => {
674
657
  return currentIds.includes(link.get(thingName));
675
658
  }).map((x) => x.get(targetRelation.thing));
676
- const targetRelationEntities = cache.entities.get(
677
- targetRelation.thing
678
- );
659
+ const targetRelationEntities = cache.entities.get(targetRelation.thing);
679
660
  if (!targetRelationEntities)
680
661
  return null;
681
662
  const children = filterChildrenEntities(
@@ -769,9 +750,7 @@ var buildTQLQuery = async (req) => {
769
750
  const queryStr = `match $${thingPath} isa ${thingPath}, has attribute $attribute ${localFiltersTql} ${idFilter} group $${thingPath};`;
770
751
  const rolesObj = allRoles.map((role) => {
771
752
  if (!role.schema.playedBy || [...new Set(role.schema.playedBy?.map((x) => x.thing))].length !== 1) {
772
- throw new Error(
773
- "Unsupported: Role played by multiple linkfields or none"
774
- );
753
+ throw new Error("Unsupported: Role played by multiple linkfields or none");
775
754
  }
776
755
  const roleThingName = role.schema.playedBy[0].thing;
777
756
  return {
@@ -816,16 +795,9 @@ var parseBQLQuery = async (req) => {
816
795
  if (!currentSchema) {
817
796
  throw new Error(`Thing '${rawBqlQuery}' not found in schema`);
818
797
  }
819
- const { unidentifiedFields, localFilters, nestedFilters } = getCurrentFields(
820
- currentSchema,
821
- rawBqlQuery
822
- );
798
+ const { unidentifiedFields, localFilters, nestedFilters } = getCurrentFields(currentSchema, rawBqlQuery);
823
799
  if (unidentifiedFields && unidentifiedFields.length > 0) {
824
- throw new Error(
825
- `Unknown fields: [${unidentifiedFields.join(",")}] in ${JSON.stringify(
826
- rawBqlQuery
827
- )}`
828
- );
800
+ throw new Error(`Unknown fields: [${unidentifiedFields.join(",")}] in ${JSON.stringify(rawBqlQuery)}`);
829
801
  }
830
802
  req.bqlRequest = {
831
803
  query: {
@@ -920,9 +892,7 @@ var dispatchPipeline = async (req, res) => {
920
892
  if (!$fields || !Array.isArray($fields)) {
921
893
  return;
922
894
  }
923
- const expandedLinkAndRoleFields = $fields.filter(
924
- (f) => typeof f !== "string" && f.$path
925
- );
895
+ const expandedLinkAndRoleFields = $fields.filter((f) => typeof f !== "string" && f.$path);
926
896
  const nestedThingsByLF = $thing.linkFields?.filter(
927
897
  (linkField) => expandedLinkAndRoleFields.findIndex(
928
898
  (expanded) => expanded.$path === linkField.path
@@ -997,14 +967,12 @@ var buildTQLMutation = async (req) => {
997
967
  const attributes = (0, import_radash7.listify)(node, (k, v) => {
998
968
  if (k.startsWith("$") || k === idField || !v)
999
969
  return "";
1000
- const currentDataField = currentSchema.dataFields?.find(
1001
- (x) => x.path === k
1002
- );
970
+ const currentDataField = currentSchema.dataFields?.find((x) => x.path === k);
1003
971
  const fieldDbPath = currentDataField?.path;
1004
972
  if (!fieldDbPath) {
1005
973
  return ``;
1006
974
  }
1007
- const dbField = currentDataField.shared ? fieldDbPath : `${thingDbPath}\xB7${fieldDbPath}`;
975
+ const dbField = currentDataField.dbPath;
1008
976
  if (["TEXT", "ID", "EMAIL"].includes(currentDataField.contentType)) {
1009
977
  return `has ${dbField} '${v}'`;
1010
978
  }
@@ -1020,28 +988,22 @@ var buildTQLMutation = async (req) => {
1020
988
  }
1021
989
  return `has ${dbField} ${new Date(v).toISOString().replace("Z", "")}`;
1022
990
  }
1023
- throw new Error(
1024
- `Unsupported contentType ${currentDataField.contentType}`
1025
- );
991
+ throw new Error(`Unsupported contentType ${currentDataField.contentType}`);
1026
992
  }).filter((x) => x);
1027
993
  const attributesVar = `$${id}-atts`;
1028
994
  const matchAttributes = (0, import_radash7.listify)(node, (k, v) => {
1029
995
  if (k.startsWith("$") || k === idField || !v)
1030
996
  return "";
1031
- const currentDataField = currentSchema.dataFields?.find(
1032
- (x) => x.path === k
1033
- );
997
+ const currentDataField = currentSchema.dataFields?.find((x) => x.path === k);
1034
998
  const fieldDbPath = currentDataField?.path;
1035
999
  if (!fieldDbPath) {
1036
1000
  return ``;
1037
1001
  }
1038
- const dbField = currentDataField.shared ? fieldDbPath : `${thingDbPath}\xB7${fieldDbPath}`;
1002
+ const dbField = currentDataField.dbPath;
1039
1003
  return `{${attributesVar} isa ${dbField};}`;
1040
1004
  }).filter((x) => x);
1041
1005
  const idFieldValue = node[idField] || node.$id;
1042
- const idDataField = currentSchema.dataFields?.find(
1043
- (x) => x.path === idField
1044
- );
1006
+ const idDataField = currentSchema.dataFields?.find((x) => x.path === idField);
1045
1007
  const idDefaultValue = node.$op === "create" ? idDataField?.default?.value() : null;
1046
1008
  const idValue = idFieldValue || idDefaultValue;
1047
1009
  const idAttributes = idValue ? [`has ${idField} '${idValue}'`] : [];
@@ -1099,9 +1061,7 @@ var buildTQLMutation = async (req) => {
1099
1061
  }
1100
1062
  return { path: roleDbPath, id: v };
1101
1063
  }).filter((x) => x).flat();
1102
- const fromRoleFieldsTql = fromRoleFields.map(
1103
- (x) => x ? `${x.path}: $${x.id}` : ""
1104
- );
1064
+ const fromRoleFieldsTql = fromRoleFields.map((x) => x ? `${x.path}: $${x.id}` : "");
1105
1065
  const roles = fromRoleFields.length > 0 ? `( ${fromRoleFieldsTql.join(" , ")} )` : "";
1106
1066
  const relationTql = !roles ? "" : `$${id} ${roles} ${node[Symbol.for("edgeType")] === "linkField" ? `isa ${relationDbPath}` : ""}`;
1107
1067
  const getInsertions = () => {
@@ -1133,17 +1093,11 @@ var buildTQLMutation = async (req) => {
1133
1093
  if (Array.isArray(nodes)) {
1134
1094
  return nodes.map((x) => {
1135
1095
  const { insertionMatch: insertionMatch2, deletionMatch: deletionMatch2, insertion: insertion2, deletion: deletion2 } = typeQL(x);
1136
- return (0, import_radash7.shake)(
1137
- { insertionMatch: insertionMatch2, deletionMatch: deletionMatch2, insertion: insertion2, deletion: deletion2 },
1138
- (z) => !z
1139
- );
1096
+ return (0, import_radash7.shake)({ insertionMatch: insertionMatch2, deletionMatch: deletionMatch2, insertion: insertion2, deletion: deletion2 }, (z) => !z);
1140
1097
  }).filter((y) => y);
1141
1098
  }
1142
1099
  const { insertionMatch, deletionMatch, insertion, deletion } = typeQL(nodes);
1143
- return (0, import_radash7.shake)(
1144
- { insertionMatch, deletionMatch, insertion, deletion },
1145
- (z) => !z
1146
- );
1100
+ return (0, import_radash7.shake)({ insertionMatch, deletionMatch, insertion, deletion }, (z) => !z);
1147
1101
  };
1148
1102
  const nodeOperations = toTypeQL(mutation.things);
1149
1103
  const arrayNodeOperations = Array.isArray(nodeOperations) ? nodeOperations : [nodeOperations];
@@ -1193,16 +1147,11 @@ var parseBQLMutation = async (req) => {
1193
1147
  ...linkFields.map((x) => ({ fieldType: "linkField", path: x })),
1194
1148
  ...roleFields.map((x) => ({ fieldType: "roleField", path: x }))
1195
1149
  ]?.forEach((currentField) => {
1196
- const currentLinkFieldSchema = currentSchema.linkFields?.find(
1197
- (x) => x.path === currentField.path
1198
- );
1150
+ const currentLinkFieldSchema = currentSchema.linkFields?.find((x) => x.path === currentField.path);
1199
1151
  const currentValue = value[currentField.path];
1200
1152
  if (currentValue === void 0)
1201
1153
  return;
1202
- const currentRoleFieldSchema = "roles" in currentSchema ? oFind(
1203
- currentSchema.roles,
1204
- (k) => k === currentField.path
1205
- ) : null;
1154
+ const currentRoleFieldSchema = "roles" in currentSchema ? oFind(currentSchema.roles, (k) => k === currentField.path) : null;
1206
1155
  const currentFieldSchema = currentLinkFieldSchema || currentRoleFieldSchema;
1207
1156
  if (currentRoleFieldSchema && [...new Set(currentRoleFieldSchema.playedBy?.map((x) => x.thing))].length !== 1) {
1208
1157
  throw new Error(
@@ -1223,24 +1172,15 @@ var parseBQLMutation = async (req) => {
1223
1172
  };
1224
1173
  const relation = getCurrentRelation();
1225
1174
  const relationSchema = relation === "$self" ? currentSchema : schema.relations[relation];
1226
- const currentFieldRole = oFind(
1227
- relationSchema.roles,
1228
- (k, _v) => k === currentField.path
1229
- );
1175
+ const currentFieldRole = oFind(relationSchema.roles, (k, _v) => k === currentField.path);
1230
1176
  if (currentFieldRole?.playedBy?.length === 0)
1231
- throw new Error(
1232
- `unused role: ${currentPath}.${currentField.path}`
1233
- );
1177
+ throw new Error(`unused role: ${currentPath}.${currentField.path}`);
1234
1178
  if (!currentFieldSchema) {
1235
1179
  throw new Error(`Field ${currentField.path} not found in schema`);
1236
1180
  }
1237
1181
  const oppositeFields = currentLinkFieldSchema?.oppositeLinkFieldsPlayedBy || currentRoleFieldSchema?.playedBy;
1238
1182
  if (!oppositeFields) {
1239
- throw new Error(
1240
- `No opposite fields found for ${JSON.stringify(
1241
- currentFieldSchema
1242
- )}`
1243
- );
1183
+ throw new Error(`No opposite fields found for ${JSON.stringify(currentFieldSchema)}`);
1244
1184
  }
1245
1185
  if ([...new Set(oppositeFields?.map((x) => x.thing))].length > 1)
1246
1186
  throw new Error(
@@ -1252,9 +1192,7 @@ var parseBQLMutation = async (req) => {
1252
1192
  value[currentField.path] = { $op: "unlink" };
1253
1193
  }
1254
1194
  if (currentFieldSchema.cardinality === "ONE" && Array.isArray(currentValue)) {
1255
- throw new Error(
1256
- `Can't have an array in a cardinality === ONE link field`
1257
- );
1195
+ throw new Error(`Can't have an array in a cardinality === ONE link field`);
1258
1196
  }
1259
1197
  if (currentValue.$entity || currentValue.$relation)
1260
1198
  return;
@@ -1317,105 +1255,81 @@ var parseBQLMutation = async (req) => {
1317
1255
  const fillBlocks = (blocks) => {
1318
1256
  return (0, import_immer3.default)(
1319
1257
  blocks,
1320
- (draft) => (0, import_object_traversal3.traverse)(
1321
- draft,
1322
- ({ parent, key, value: val, meta }) => {
1323
- if ((0, import_radash8.isObject)(val)) {
1324
- if (Object.keys(val).length === 0) {
1325
- throw new Error("Empty object!");
1326
- }
1327
- const value = val;
1328
- const nodePathArray = meta.nodePath?.split(".");
1329
- const notRoot = nodePathArray?.filter((x) => Number.isNaN(parseInt(x, 10))).join(".");
1330
- const currentSchema = getCurrentSchema(schema, value);
1331
- const { unidentifiedFields, dataFields, roleFields, linkFields } = getCurrentFields(currentSchema, value);
1332
- const hasUpdatedDataFields = Object.keys(value).some(
1333
- (x) => dataFields?.includes(x)
1334
- );
1335
- const hasUpdatedChildren = Object.keys(value).some(
1336
- (x) => [...roleFields, ...linkFields]?.includes(x)
1337
- );
1338
- const getOp = () => {
1339
- if (value.$op)
1340
- return value.$op;
1341
- if ((value.$id || value.$filter) && hasUpdatedDataFields)
1342
- return "update";
1343
- if ((value.$id || value.$filter) && notRoot && !hasUpdatedDataFields && !hasUpdatedChildren)
1344
- return "link";
1345
- if (!value.$filter && !value.$id)
1346
- return "create";
1347
- if ((value.$id || value.$filter) && !hasUpdatedDataFields && hasUpdatedChildren)
1348
- return "noop";
1349
- throw new Error("Wrong op");
1350
- };
1351
- if (!value.$op)
1352
- value.$op = getOp();
1353
- if (!parent)
1354
- value.$parentKey = "";
1355
- if (!(value.$id || value.$tempId || value.$filter) && ["delete", "link", "update", "unlink"].includes(value.$op)) {
1356
- throw new Error(
1357
- "Targeted operations (update, delete, link & unlink) require an $id or a $filter"
1358
- );
1359
- }
1360
- if (typeof parent === "object") {
1361
- const ArParent = Array.isArray(parent);
1362
- if (ArParent)
1363
- value[Symbol.for("index")] = key;
1364
- value[Symbol.for("path")] = meta.nodePath;
1365
- value[Symbol.for("isRoot")] = !notRoot;
1366
- value[Symbol.for("depth")] = notRoot?.split(".").length;
1367
- }
1368
- if (!value.$entity && !value.$relation) {
1369
- throw new Error(
1370
- `Node ${JSON.stringify(value)} without $entity/$relation`
1371
- );
1372
- }
1373
- const { idFields, computedFields } = currentSchema;
1374
- if (!idFields)
1375
- throw new Error("No idFields found");
1376
- const idField = idFields[0];
1377
- if (value[idField] && !value.$id) {
1378
- value.$id = value[idField];
1258
+ (draft) => (0, import_object_traversal3.traverse)(draft, ({ parent, key, value: val, meta }) => {
1259
+ if ((0, import_radash8.isObject)(val)) {
1260
+ if (Object.keys(val).length === 0) {
1261
+ throw new Error("Empty object!");
1262
+ }
1263
+ const value = val;
1264
+ const nodePathArray = meta.nodePath?.split(".");
1265
+ const notRoot = nodePathArray?.filter((x) => Number.isNaN(parseInt(x, 10))).join(".");
1266
+ const currentSchema = getCurrentSchema(schema, value);
1267
+ const { unidentifiedFields, dataFields, roleFields, linkFields } = getCurrentFields(currentSchema, value);
1268
+ const hasUpdatedDataFields = Object.keys(value).some((x) => dataFields?.includes(x));
1269
+ const hasUpdatedChildren = Object.keys(value).some((x) => [...roleFields, ...linkFields]?.includes(x));
1270
+ const getOp = () => {
1271
+ if (value.$op)
1272
+ return value.$op;
1273
+ if ((value.$id || value.$filter) && hasUpdatedDataFields)
1274
+ return "update";
1275
+ if ((value.$id || value.$filter) && notRoot && !hasUpdatedDataFields && !hasUpdatedChildren)
1276
+ return "link";
1277
+ if (!value.$filter && !value.$id)
1278
+ return "create";
1279
+ if ((value.$id || value.$filter) && !hasUpdatedDataFields && hasUpdatedChildren)
1280
+ return "noop";
1281
+ throw new Error("Wrong op");
1282
+ };
1283
+ if (!value.$op)
1284
+ value.$op = getOp();
1285
+ if (!parent)
1286
+ value.$parentKey = "";
1287
+ if (!(value.$id || value.$tempId || value.$filter) && ["delete", "link", "update", "unlink"].includes(value.$op)) {
1288
+ throw new Error("Targeted operations (update, delete, link & unlink) require an $id or a $filter");
1289
+ }
1290
+ if (typeof parent === "object") {
1291
+ const ArParent = Array.isArray(parent);
1292
+ if (ArParent)
1293
+ value[Symbol.for("index")] = key;
1294
+ value[Symbol.for("path")] = meta.nodePath;
1295
+ value[Symbol.for("isRoot")] = !notRoot;
1296
+ value[Symbol.for("depth")] = notRoot?.split(".").length;
1297
+ }
1298
+ if (!value.$entity && !value.$relation) {
1299
+ throw new Error(`Node ${JSON.stringify(value)} without $entity/$relation`);
1300
+ }
1301
+ const { idFields, computedFields } = currentSchema;
1302
+ if (!idFields)
1303
+ throw new Error("No idFields found");
1304
+ const idField = idFields[0];
1305
+ if (value[idField] && !value.$id) {
1306
+ value.$id = value[idField];
1307
+ }
1308
+ const filledFields = (0, import_radash8.listify)(value, (attKey, v) => v ? attKey : void 0);
1309
+ const missingComputedFields = computedFields.filter((x) => !filledFields.includes(x));
1310
+ missingComputedFields.forEach((fieldPath) => {
1311
+ const currentFieldDef = currentSchema.dataFields?.find((x) => x.path === fieldPath);
1312
+ const currentLinkDef = currentSchema.linkFields?.find((x) => x.path === fieldPath);
1313
+ const currentLinkedDef = currentLinkDef?.oppositeLinkFieldsPlayedBy[0];
1314
+ const currentRoleDef = "roles" in currentSchema ? oFind(currentSchema.roles, (k, _v) => k === fieldPath) : void 0;
1315
+ const currentDef = currentFieldDef || currentLinkedDef || currentRoleDef;
1316
+ if (!currentDef) {
1317
+ throw new Error(`no field Def for ${fieldPath}`);
1379
1318
  }
1380
- const filledFields = (0, import_radash8.listify)(
1381
- value,
1382
- (attKey, v) => v ? attKey : void 0
1383
- );
1384
- const missingComputedFields = computedFields.filter(
1385
- (x) => !filledFields.includes(x)
1386
- );
1387
- missingComputedFields.forEach((fieldPath) => {
1388
- const currentFieldDef = currentSchema.dataFields?.find(
1389
- (x) => x.path === fieldPath
1390
- );
1391
- const currentLinkDef = currentSchema.linkFields?.find(
1392
- (x) => x.path === fieldPath
1393
- );
1394
- const currentLinkedDef = currentLinkDef?.oppositeLinkFieldsPlayedBy[0];
1395
- const currentRoleDef = "roles" in currentSchema ? oFind(currentSchema.roles, (k, _v) => k === fieldPath) : void 0;
1396
- const currentDef = currentFieldDef || currentLinkedDef || currentRoleDef;
1397
- if (!currentDef) {
1398
- throw new Error(`no field Def for ${fieldPath}`);
1319
+ if (fieldPath === idField && value.$op === "create" && !value[fieldPath]) {
1320
+ const defaultValue = "default" in currentDef ? currentDef.default?.value() : void 0;
1321
+ if (!defaultValue) {
1322
+ throw new Error(`No default value for ${fieldPath}`);
1399
1323
  }
1400
- if (fieldPath === idField && value.$op === "create" && !value[fieldPath]) {
1401
- const defaultValue = "default" in currentDef ? currentDef.default?.value() : void 0;
1402
- if (!defaultValue) {
1403
- throw new Error(`No default value for ${fieldPath}`);
1404
- }
1405
- value[fieldPath] = defaultValue;
1406
- value.$id = defaultValue;
1407
- }
1408
- });
1409
- if (unidentifiedFields.length > 0) {
1410
- throw new Error(
1411
- `Unknown fields: [${unidentifiedFields.join(
1412
- ","
1413
- )}] in ${JSON.stringify(value)}`
1414
- );
1324
+ value[fieldPath] = defaultValue;
1325
+ value.$id = defaultValue;
1415
1326
  }
1327
+ });
1328
+ if (unidentifiedFields.length > 0) {
1329
+ throw new Error(`Unknown fields: [${unidentifiedFields.join(",")}] in ${JSON.stringify(value)}`);
1416
1330
  }
1417
1331
  }
1418
- )
1332
+ })
1419
1333
  );
1420
1334
  };
1421
1335
  const filledBQLMutation = fillBlocks(withObjects);
@@ -1450,9 +1364,7 @@ var parseBQLMutation = async (req) => {
1450
1364
  if (value.$op === "link" || value.$op === "unlink") {
1451
1365
  if (value.$id || value.$filter) {
1452
1366
  if (value.$tempId) {
1453
- throw new Error(
1454
- "can't specify a existing and a new element at once. Use an id/filter or a tempId"
1455
- );
1367
+ throw new Error("can't specify a existing and a new element at once. Use an id/filter or a tempId");
1456
1368
  }
1457
1369
  nodes.push({ ...value, $op: "noop" });
1458
1370
  }
@@ -1502,10 +1414,7 @@ var parseBQLMutation = async (req) => {
1502
1414
  "An id must be specified either in the mutation or has tu have a default value in the schema"
1503
1415
  );
1504
1416
  }
1505
- const rolesObjFiltered = oFilter(
1506
- val,
1507
- (k, _v) => roleFieldPaths.includes(k)
1508
- );
1417
+ const rolesObjFiltered = oFilter(val, (k, _v) => roleFieldPaths.includes(k));
1509
1418
  const rolesObjOnlyIds = (0, import_radash8.mapEntries)(rolesObjFiltered, (k, v) => {
1510
1419
  return [k, v.$id || v];
1511
1420
  });
@@ -1538,26 +1447,18 @@ var parseBQLMutation = async (req) => {
1538
1447
  (x) => x.$op === "link" || x.$op === "create"
1539
1448
  )
1540
1449
  );
1541
- const rolesWithLinksFiltered = (0, import_radash8.mapEntries)(
1542
- rolesWithLinks,
1543
- (k, v) => [
1544
- k,
1545
- v.filter((x) => x.$op === "link" || x.$op === "create").map((y) => y.$id)
1546
- ]
1547
- );
1450
+ const rolesWithLinksFiltered = (0, import_radash8.mapEntries)(rolesWithLinks, (k, v) => [
1451
+ k,
1452
+ v.filter((x) => x.$op === "link" || x.$op === "create").map((y) => y.$id)
1453
+ ]);
1548
1454
  const rolesWithUnlinks = oFilter(
1549
1455
  rolesObjOnlyIds,
1550
- (_k, v) => v.some(
1551
- (x) => x.$op === "unlink" || x.$op === "delete"
1552
- )
1553
- );
1554
- const rolesWithUnlinksFiltered = (0, import_radash8.mapEntries)(
1555
- rolesWithUnlinks,
1556
- (k, v) => [
1557
- k,
1558
- v.filter((x) => x.$op === "unlink" || x.$op === "delete").map((y) => y.$id)
1559
- ]
1456
+ (_k, v) => v.some((x) => x.$op === "unlink" || x.$op === "delete")
1560
1457
  );
1458
+ const rolesWithUnlinksFiltered = (0, import_radash8.mapEntries)(rolesWithUnlinks, (k, v) => [
1459
+ k,
1460
+ v.filter((x) => x.$op === "unlink" || x.$op === "delete").map((y) => y.$id)
1461
+ ]);
1561
1462
  const rolesWithReplaces = {};
1562
1463
  [
1563
1464
  { op: "link", obj: rolesWithLinksFiltered },
@@ -1585,17 +1486,13 @@ var parseBQLMutation = async (req) => {
1585
1486
  };
1586
1487
  const [parsedThings, parsedEdges] = listNodes(filledBQLMutation);
1587
1488
  const mergedEdges = parsedEdges.reduce((acc, curr) => {
1588
- const existingEdge = acc.find(
1589
- (r) => r.$id === curr.$id && r.$relation === curr.$relation
1590
- );
1489
+ const existingEdge = acc.find((r) => r.$id === curr.$id && r.$relation === curr.$relation);
1591
1490
  if (existingEdge) {
1592
1491
  const newRelation = {
1593
1492
  ...existingEdge,
1594
1493
  ...curr
1595
1494
  };
1596
- const newAcc = acc.filter(
1597
- (r) => r.$id !== curr.$id || r.$relation !== curr.$relation
1598
- );
1495
+ const newAcc = acc.filter((r) => r.$id !== curr.$id || r.$relation !== curr.$relation);
1599
1496
  return [...newAcc, newRelation];
1600
1497
  }
1601
1498
  return [...acc, curr];
@@ -1643,13 +1540,7 @@ var runTQLMutation = async (req, res) => {
1643
1540
 
1644
1541
  // src/pipeline/pipeline.ts
1645
1542
  var Pipelines = {
1646
- query: [
1647
- parseBQLQuery,
1648
- buildTQLQuery,
1649
- runTQLQuery,
1650
- parseTQLRes,
1651
- dispatchPipeline
1652
- ],
1543
+ query: [parseBQLQuery, buildTQLQuery, runTQLQuery, parseTQLRes, dispatchPipeline],
1653
1544
  mutation: [parseBQLMutation, buildTQLMutation, runTQLMutation, parseTQLRes]
1654
1545
  };
1655
1546
  var finalPipeline = [buildBQLTree];
@@ -1658,12 +1549,7 @@ var runPipeline = async (pipeline, req, res = {}, root = true) => {
1658
1549
  const next = await operation(req, res);
1659
1550
  if (next && Array.isArray(next)) {
1660
1551
  for (const nextPipeline of next) {
1661
- await runPipeline(
1662
- nextPipeline.pipeline,
1663
- nextPipeline.req,
1664
- nextPipeline.res,
1665
- false
1666
- );
1552
+ await runPipeline(nextPipeline.pipeline, nextPipeline.req, nextPipeline.res, false);
1667
1553
  }
1668
1554
  }
1669
1555
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blitznocode/blitz-orm",
3
- "version": "0.0.43",
3
+ "version": "0.0.44",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
@@ -53,12 +53,6 @@
53
53
  "tsup": "^6.5.0",
54
54
  "typescript": "^4.9.5"
55
55
  },
56
- "peerDependencies": {},
57
- "peerDependenciesMeta": {
58
- "essentials": {
59
- "optional": true
60
- }
61
- },
62
56
  "description": "Blitz-orm is a public package that can be open-sourced",
63
57
  "bugs": {
64
58
  "url": "https://github.com/Blitzapps/blitz-orm/issues"
@@ -68,7 +62,9 @@
68
62
  "test": "tests"
69
63
  },
70
64
  "keywords": [
71
- "ORM"
65
+ "ORM",
66
+ "database",
67
+ "graph-database"
72
68
  ],
73
69
  "author": "blitznocode"
74
70
  }