entodicton 9.5.1-beta.21 → 9.5.1-beta.23

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/client.js CHANGED
@@ -12,9 +12,8 @@ const _ = require('lodash')
12
12
  const stringify = require('json-stable-stringify')
13
13
  const Lines = require('./lines')
14
14
  const flattens = require('./src/flatten')
15
- const { appendNoDups, updateQueries, safeNoDups, stableId, where, suggestAssociationsFix, suggestAssociationsFixFromSummaries, validProps } = require('./src/helpers')
15
+ const { sortJson, appendNoDups, updateQueries, safeNoDups, stableId, where, suggestAssociationsFix, suggestAssociationsFixFromSummaries, validProps } = require('./src/helpers')
16
16
  const runtime = require('./runtime')
17
- const sortJson = runtime.sortJson
18
17
  const debug = require('./src/debug')
19
18
 
20
19
  const getConfig_getObjectsCheck = (config, testConfig) => {
@@ -69,6 +68,7 @@ const pickObjects = (config, testConfig, getObjects) => {
69
68
  if (!objects) {
70
69
  throw new Error(`In the checks for ${config.name} the KM ${km} does not exist`)
71
70
  }
71
+
72
72
  if (checks[km] && checks[km].find((check) => check.match && check.apply)) {
73
73
  projection[km] = project2(objects, checks[km])
74
74
  } else {
@@ -973,7 +973,7 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
973
973
  if (instance.fragments) {
974
974
  pr = instance.fragments[index]
975
975
  }
976
- return Object.assign({}, toProperties(query), { property: 'fragments', previousResults: pr, skipSemantics: false })
976
+ return Object.assign({}, toProperties(query), { property: 'fragments', previousResults: pr, skipSemantics: true })
977
977
  }
978
978
 
979
979
  const looper = async (configs) => {
package/package.json CHANGED
@@ -70,9 +70,8 @@
70
70
  "node-fetch": "^2.6.1",
71
71
  "readline": "^1.3.0",
72
72
  "scriptjs": "^2.5.9",
73
- "sort-json": "^2.0.0",
74
73
  "uuid": "^8.3.2"
75
74
  },
76
- "version": "9.5.1-beta.21",
75
+ "version": "9.5.1-beta.23",
77
76
  "license": "UNLICENSED"
78
77
  }
package/runtime.js CHANGED
@@ -13,7 +13,6 @@ module.exports = {
13
13
  ArgumentParser,
14
14
  readline: require('readline'),
15
15
  jsonDiff: require('json-diff'),
16
- sortJson: require('sort-json'),
17
16
  util: require('util'),
18
17
  performance: require('perf_hooks')
19
18
  }
package/src/config.js CHANGED
@@ -515,8 +515,43 @@ const handleCalculatedProps = (baseConfig, moreConfig, { addFirst, uuid } = {})
515
515
  if (moreConfig.bridges) {
516
516
  moreConfig.bridges = moreConfig.bridges.map((bridge) => {
517
517
  bridge = { ...bridge }
518
- const valid = ['after', 'conditional', 'associations', 'before', 'bridge', 'check', 'disabled', 'scope', 'skipable', 'return_type_selector', 'evaluator', 'evaluators', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'operator', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
519
- 'level', 'optional', 'selector', 'separators', 'semantic', 'semantics', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where', 'uuid']
518
+ const valid = [
519
+ 'after',
520
+ 'associations',
521
+ 'before',
522
+ 'bridge',
523
+ 'check',
524
+ 'children',
525
+ 'conditional',
526
+ 'convolution',
527
+ 'disabled',
528
+ 'enhanced_associations',
529
+ 'evaluator',
530
+ 'evaluators',
531
+ 'generatorp',
532
+ 'generatorpr',
533
+ 'generatorr',
534
+ 'generators',
535
+ 'id',
536
+ 'inverted',
537
+ 'isA',
538
+ 'level',
539
+ 'levelSpecificHierarchy',
540
+ 'localHierarchy',
541
+ 'operator',
542
+ 'optional',
543
+ 'parents',
544
+ 'return_type_selector',
545
+ 'scope',
546
+ 'selector',
547
+ 'semantic',
548
+ 'semantics',
549
+ 'separators',
550
+ 'skipable',
551
+ 'uuid',
552
+ 'where',
553
+ 'words', /Bridge$/,
554
+ ]
520
555
  helpers.validProps(valid, bridge, 'bridge')
521
556
  handleBridgeProps(baseConfig, bridge, { addFirst, uuid })
522
557
  return bridge
@@ -679,7 +714,7 @@ function setWordsUUIDs (words, uuid) {
679
714
  for (const key in literals) {
680
715
  literals[key] = literals[key].map((o) => Object.assign(o, { uuid }))
681
716
  }
682
- const patterns = words.patterns
717
+ const patterns = words.patterns || []
683
718
  for (const pattern of patterns) {
684
719
  pattern.defs.map((def) => Object.assign(def, { uuid }))
685
720
  }
@@ -1137,10 +1172,20 @@ class Config {
1137
1172
  }
1138
1173
  }
1139
1174
 
1140
- fragment (args, query) {
1175
+ // mappings are optional
1176
+ async fragment (args, query, mappings) {
1141
1177
  const fragment = this.getFragment(query)
1142
1178
  if (fragment) {
1143
- return fragmentInstantiator(args, fragment.contexts)
1179
+ let fi = fragmentInstantiator(args, fragment.contexts)
1180
+ if (mappings) {
1181
+ fi = await fi
1182
+ return fi.instantiate([{
1183
+ match: ({context}) => !!mappings[context.value], // is the value in the mappings
1184
+ apply: ({context}) => Object.assign(context, mappings[context.value]),
1185
+ }])
1186
+ } else {
1187
+ return fi
1188
+ }
1144
1189
  }
1145
1190
  }
1146
1191
 
@@ -118,8 +118,9 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
118
118
  // args.listable = listable(hierarchy)
119
119
  // args.asList = asList
120
120
  args.retry = () => { throw new RetryError() }
121
- args.fragments = (query) => {
122
- return config.fragment(args, query)
121
+ // mappings are optional
122
+ args.fragments = (query, mappings) => {
123
+ return config.fragment(args, query, mappings)
123
124
  }
124
125
  args.fragmentMapper = (values, fromModelQuery, toModelQuery) => {
125
126
  return config.fragmentMapper(args, values, fromModelQuery, toModelQuery)
package/src/fragments.js CHANGED
@@ -30,7 +30,11 @@ function fragmentInstantiator (args, contexts) {
30
30
  todo.push({ context: context[key], path: [...path, key] })
31
31
  }
32
32
  }
33
- return instantiated
33
+ if (contexts.length == 1 && instantiated.length == 1) {
34
+ return instantiated[0]
35
+ } else {
36
+ return instantiated
37
+ }
34
38
  }
35
39
  })
36
40
  }
package/src/helpers.js CHANGED
@@ -292,8 +292,53 @@ const hashCode = (str) => {
292
292
  return hash
293
293
  }
294
294
 
295
- const sortJson = (json) => {
296
- return json
295
+ /**
296
+ * Recursively sorts object keys alphabetically.
297
+ * Fully handles arrays (including objects inside arrays) and preserves Date/other non-plain objects.
298
+ *
299
+ * @param {any} input - The value to sort (object, array, primitive, etc.)
300
+ * @param {Object} [options]
301
+ * - ignoreCase: boolean (default false) – case-insensitive sort
302
+ * - reverse: boolean (default false) – reverse alphabetical order
303
+ * @returns {any} New sorted value
304
+ */
305
+ function sortJson(input, options = {}) {
306
+ const { ignoreCase = false, reverse = false } = options;
307
+
308
+ // Helper: is this a plain object {} (not Array, Date, Map, null, etc.)
309
+ function isPlainObject(value) {
310
+ return value !== null && typeof value === 'object' && value.constructor === Object;
311
+ }
312
+
313
+ // Handle arrays: map over elements and recurse
314
+ if (Array.isArray(input)) {
315
+ return input.map(item => sortJson(item, options));
316
+ }
317
+
318
+ // If not a plain object, return unchanged (preserves Date, Map, Set, primitives, etc.)
319
+ if (!isPlainObject(input)) {
320
+ return input;
321
+ }
322
+
323
+ // Sorter for keys
324
+ const sorter = (a, b) => {
325
+ const A = ignoreCase ? a.toLowerCase() : a;
326
+ const B = ignoreCase ? b.toLowerCase() : b;
327
+ return reverse ? B.localeCompare(A) : A.localeCompare(B);
328
+ };
329
+
330
+ // Build new sorted object
331
+ const sorted = {};
332
+
333
+ Object.keys(input)
334
+ .sort(sorter)
335
+ .forEach(key => {
336
+ const value = input[key];
337
+ // Always recurse: handles nested objects and arrays properly
338
+ sorted[key] = sortJson(value, options);
339
+ });
340
+
341
+ return sorted;
297
342
  }
298
343
 
299
344
  const validProps = (valids, object, type) => {
package/src/project2.js CHANGED
@@ -3,6 +3,13 @@ function project(source, filters) {
3
3
  return source
4
4
  }
5
5
 
6
+ function isPlainObject(obj) {
7
+ return Object.prototype.toString.call(obj) === '[object Object]';
8
+ }
9
+ if (!isPlainObject(source) && !Array.isArray(source)) {
10
+ return source
11
+ }
12
+
6
13
  if (Object.keys(source).length === 0 && filters.length === 0) {
7
14
  return {};
8
15
  }