theprogrammablemind_4wp 9.5.1-beta.9 → 9.6.0
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 +71 -28
- package/lines.js +1 -1
- package/package.json +1 -2
- package/runtime.js +0 -1
- package/src/config.js +225 -34
- package/src/configHelpers.js +54 -32
- package/src/fragments.js +26 -69
- package/src/generators.js +19 -14
- package/src/helpers.js +47 -2
- package/src/project2.js +54 -4
- package/src/semantics.js +12 -7
package/client.js
CHANGED
|
@@ -12,10 +12,9 @@ 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
|
|
18
|
-
const debug = require('./src/debug')
|
|
17
|
+
const db = require('./src/debug')
|
|
19
18
|
|
|
20
19
|
const getConfig_getObjectsCheck = (config, testConfig) => {
|
|
21
20
|
let testConfigName = config.name
|
|
@@ -46,33 +45,33 @@ const getSuggestionMessage = (suggestion) => {
|
|
|
46
45
|
return `Try adding this to the associations: { context: ${JSON.stringify(getSuggestion(suggestion))}, choose: <indexOfMainElement> },\n If that does not work look at the logs and check when the operators become wrong during an interation. Deduce the change based on the previous iteration and what operator was applied.`
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
const getConfig_getContextCheck = (testConfig) => {
|
|
50
|
-
return (testConfig.checks && testConfig.checks.context) || []
|
|
51
|
-
}
|
|
52
|
-
|
|
53
48
|
const pickContext = (contextChecks) => (context) => {
|
|
54
49
|
return project2(context, contextChecks)
|
|
55
50
|
}
|
|
56
51
|
|
|
57
52
|
const pickObjects = (config, testConfig, getObjects) => {
|
|
58
|
-
/*
|
|
59
|
-
let testConfigName = config.name
|
|
60
|
-
if (testConfig.testModuleName) {
|
|
61
|
-
objects = getObjects(config.config.objects)(config.getConfigs()[testConfig.testModuleName].uuid)
|
|
62
|
-
testConfigName = testConfig.testModuleName
|
|
63
|
-
}
|
|
64
|
-
*/
|
|
65
53
|
const checks = getConfig_getObjectsCheck(config, testConfig)
|
|
54
|
+
const contextChecks = config.getContextChecks()
|
|
66
55
|
const projection = {}
|
|
67
56
|
for (const km in checks) {
|
|
68
57
|
const objects = getObjects(km)
|
|
69
58
|
if (!objects) {
|
|
70
59
|
throw new Error(`In the checks for ${config.name} the KM ${km} does not exist`)
|
|
71
60
|
}
|
|
72
|
-
|
|
73
|
-
|
|
61
|
+
|
|
62
|
+
if (false) {
|
|
63
|
+
if (checks[km] && checks[km].find((check) => check.match && check.apply)) {
|
|
64
|
+
projection[km] = project2(objects, checks[km])
|
|
65
|
+
} else {
|
|
66
|
+
projection[km] = project(objects, checks[km])
|
|
67
|
+
}
|
|
74
68
|
} else {
|
|
75
|
-
|
|
69
|
+
const lastIndex = contextChecks.length - 1
|
|
70
|
+
const last = contextChecks[lastIndex]
|
|
71
|
+
contextChecks[lastIndex] = { match: last.match, apply: () => [...new Set([...(checks[km] || []), ...last.apply()])] }
|
|
72
|
+
|
|
73
|
+
// projection[km] = project2(objects, [...checks[km], ...contextChecks])
|
|
74
|
+
projection[km] = project2(objects, contextChecks)
|
|
76
75
|
}
|
|
77
76
|
}
|
|
78
77
|
return projection
|
|
@@ -237,9 +236,10 @@ const doWithRetries = async (n, url, queryParams, data) => {
|
|
|
237
236
|
body: JSON.stringify(data),
|
|
238
237
|
timeout: 1000 * 60 * 5, // it does not respect this timeout so that's why I have the retries
|
|
239
238
|
headers: {
|
|
240
|
-
mode: 'no-cors',
|
|
239
|
+
// mode: 'no-cors',
|
|
241
240
|
'Content-Type': 'application/json'
|
|
242
|
-
}
|
|
241
|
+
},
|
|
242
|
+
credentials: 'same-origin',
|
|
243
243
|
})
|
|
244
244
|
if (result.ok) {
|
|
245
245
|
return JSON.parse(JSON.stringify(await result.json()))
|
|
@@ -841,7 +841,7 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
|
841
841
|
}
|
|
842
842
|
console.log(responses.trace)
|
|
843
843
|
|
|
844
|
-
if (
|
|
844
|
+
if (false) {
|
|
845
845
|
if (global.beforeObjects) {
|
|
846
846
|
console.log('objects', runtime.jsonDiff.diffString(global.beforeObjects, config.get('objects')))
|
|
847
847
|
} else {
|
|
@@ -916,7 +916,7 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
|
916
916
|
console.log('')
|
|
917
917
|
const screen_width = process.stdout.columns
|
|
918
918
|
// || 0 for when running without a console
|
|
919
|
-
const widths = [70, 10
|
|
919
|
+
const widths = Lines.addRemainder([70, 10])
|
|
920
920
|
const lines = new Lines(widths)
|
|
921
921
|
lines.setElement(0, 0, '--- The paraphrases are ----------')
|
|
922
922
|
lines.setElement(0, 2, '--- The response strings are ----------')
|
|
@@ -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:
|
|
976
|
+
return Object.assign({}, toProperties(query), { property: 'fragments', previousResults: pr, skipSemantics: true })
|
|
977
977
|
}
|
|
978
978
|
|
|
979
979
|
const looper = async (configs) => {
|
|
@@ -1327,13 +1327,32 @@ const knowledgeModuleImpl = async ({
|
|
|
1327
1327
|
parser.add_argument('-cl', '--checkForLoop', { nargs: '?', help: 'Check for loops in the priorities, Optional argument is list of operator keys to consider. For example [["banana", 0], ["food", 1]]' })
|
|
1328
1328
|
parser.add_argument('-r', '--reset', { action: 'store_true', help: 'Get the server to bypass the cache and rebuild everything' })
|
|
1329
1329
|
parser.add_argument('-q', '--query', { help: 'Run the specified query' })
|
|
1330
|
+
parser.add_argument('-f', '--filter', { help: 'for -pd only the data for the knowledge modules that start with this string will be shown' })
|
|
1330
1331
|
parser.add_argument('-ip ', '--server', { help: 'Server to run against' })
|
|
1331
1332
|
parser.add_argument('-qp ', '--queryParams', { help: 'Query params for the server call' })
|
|
1332
1333
|
parser.add_argument('-dt', '--deleteTest', { help: 'Delete the specified query from the tests file.' })
|
|
1333
1334
|
parser.add_argument('--parenthesized', { action: 'store_true', help: 'Show the generated phrases with parenthesis.' })
|
|
1334
1335
|
parser.add_argument('-c', '--clean', { help: 'Remove data from the test files. a === association' })
|
|
1335
1336
|
parser.add_argument('-od', '--objectDiff', { action: 'store_true', help: 'When showing the objects use a colour diff' })
|
|
1336
|
-
parser.add_argument('-p', '--print', { help:
|
|
1337
|
+
parser.add_argument('-p', '--print', { help:
|
|
1338
|
+
`Print the specified elements
|
|
1339
|
+
a === associations
|
|
1340
|
+
b === bridges,
|
|
1341
|
+
c === config,
|
|
1342
|
+
cc === test checks,
|
|
1343
|
+
d === objects (d for data),
|
|
1344
|
+
g === generators,
|
|
1345
|
+
h === hierarchy,
|
|
1346
|
+
ha === hierarchy ancestors,
|
|
1347
|
+
j === JSON sent to server,
|
|
1348
|
+
l === load ordering,
|
|
1349
|
+
o === operators,
|
|
1350
|
+
p === priorities,
|
|
1351
|
+
s === semantics,
|
|
1352
|
+
t === tests ordering,
|
|
1353
|
+
w === words,
|
|
1354
|
+
for example --print wb' })
|
|
1355
|
+
` })
|
|
1337
1356
|
parser.add_argument('-s', '--save', { action: 'store_true', help: 'When running with the --query flag this will save the current run to the test file. When running without the --query flag all tests will be run and resaved.' })
|
|
1338
1357
|
parser.add_argument('-fr', '--failRebuild', { action: 'store_true', help: 'If a rebuild is required fail out.' })
|
|
1339
1358
|
parser.add_argument('-sd', '--saveDeveloper', { action: 'store_true', help: 'Same as -s but the query will not show up in the info command.' })
|
|
@@ -1494,6 +1513,12 @@ const knowledgeModuleImpl = async ({
|
|
|
1494
1513
|
counter += 1
|
|
1495
1514
|
}
|
|
1496
1515
|
}
|
|
1516
|
+
if (hasArg('cc')) {
|
|
1517
|
+
for (const cc of config.getContextChecks()) {
|
|
1518
|
+
const printable = { ...cc, match: cc.match.toString(), apply: cc.apply.toString() }
|
|
1519
|
+
console.log(JSON.stringify(printable, null, 2))
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1497
1522
|
if (hasArg('c')) {
|
|
1498
1523
|
const { data } = setupProcessB({ config })
|
|
1499
1524
|
console.log('Config as sent to server')
|
|
@@ -1557,8 +1582,19 @@ const knowledgeModuleImpl = async ({
|
|
|
1557
1582
|
}
|
|
1558
1583
|
|
|
1559
1584
|
if (hasArg('d')) {
|
|
1560
|
-
|
|
1561
|
-
|
|
1585
|
+
if (args.filter) {
|
|
1586
|
+
console.log(`objects (data) filtered by ${args.filter} ================`)
|
|
1587
|
+
const projection = { namespaced: {} }
|
|
1588
|
+
for (const key of Object.keys(config.config.objects.namespaced)) {
|
|
1589
|
+
if (key.startsWith(args.filter)) {
|
|
1590
|
+
projection.namespaced[key] = config.config.objects.namespaced[key]
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
console.log(JSON.stringify(projection, null, 2))
|
|
1594
|
+
} else {
|
|
1595
|
+
console.log('objects (data) ================')
|
|
1596
|
+
console.log(JSON.stringify(config.config.objects, null, 2))
|
|
1597
|
+
}
|
|
1562
1598
|
}
|
|
1563
1599
|
|
|
1564
1600
|
if (hasArg('p')) {
|
|
@@ -2011,9 +2047,15 @@ const ensureTestFile = (module, name, type) => {
|
|
|
2011
2047
|
}
|
|
2012
2048
|
|
|
2013
2049
|
const knowledgeModule = async (...args) => {
|
|
2014
|
-
await knowledgeModuleImpl(...args).catch((e) => {
|
|
2050
|
+
await knowledgeModuleImpl(...args).catch(async (e) => {
|
|
2015
2051
|
console.error(e)
|
|
2016
|
-
|
|
2052
|
+
function sleep(ms) {
|
|
2053
|
+
return new Promise((resolve) => {
|
|
2054
|
+
setTimeout(resolve, ms);
|
|
2055
|
+
});
|
|
2056
|
+
}
|
|
2057
|
+
await sleep(1) // get the stderr to flush
|
|
2058
|
+
await process.exit(-1); // tiny trick: empty write forces flush of console.error buffer
|
|
2017
2059
|
})
|
|
2018
2060
|
}
|
|
2019
2061
|
|
|
@@ -2038,5 +2080,6 @@ module.exports = {
|
|
|
2038
2080
|
gs,
|
|
2039
2081
|
flattens,
|
|
2040
2082
|
writeTest,
|
|
2041
|
-
getConfigForTest
|
|
2083
|
+
getConfigForTest,
|
|
2084
|
+
debug: db,
|
|
2042
2085
|
}
|
package/lines.js
CHANGED
package/package.json
CHANGED
package/runtime.js
CHANGED
|
@@ -12,7 +12,6 @@ module.exports = {
|
|
|
12
12
|
ArgumentParser: 'Should not be called in the browser',
|
|
13
13
|
readline: 'Should not be called in the browser',
|
|
14
14
|
jsonDiff: 'Should not be called in the browser',
|
|
15
|
-
sortJson: 'Should not be called in the browser',
|
|
16
15
|
util: 'Should not be called in the browser',
|
|
17
16
|
performance: 'Should not be called in the browser'
|
|
18
17
|
}
|
package/src/config.js
CHANGED
|
@@ -10,7 +10,7 @@ const { ecatch } = require('./helpers')
|
|
|
10
10
|
const runtime = require('../runtime')
|
|
11
11
|
const _ = require('lodash')
|
|
12
12
|
const db = require('./debug')
|
|
13
|
-
const { fragmentInstantiator } = require('./fragments')
|
|
13
|
+
const { fragmentInstantiator, fragmentMapperInstantiator } = require('./fragments')
|
|
14
14
|
|
|
15
15
|
const debugBreak = () => {
|
|
16
16
|
// debugger
|
|
@@ -21,8 +21,6 @@ const bags = [
|
|
|
21
21
|
'semantics'
|
|
22
22
|
]
|
|
23
23
|
|
|
24
|
-
global.GORDO = true
|
|
25
|
-
|
|
26
24
|
const indent = (string, indent) => {
|
|
27
25
|
return string.replace(/^/gm, ' '.repeat(indent))
|
|
28
26
|
}
|
|
@@ -337,6 +335,8 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
|
|
337
335
|
config.addPriority({ context: [[bridge.id, bridge.level], after], choose: [0] })
|
|
338
336
|
}
|
|
339
337
|
}
|
|
338
|
+
|
|
339
|
+
// done in setTestConfig
|
|
340
340
|
if (bridge.check) {
|
|
341
341
|
if (!config.testConfig) {
|
|
342
342
|
config.testConfig = {}
|
|
@@ -347,12 +347,15 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
|
|
347
347
|
if (!config.testConfig?.checks?.context) {
|
|
348
348
|
config.testConfig.checks.context = []
|
|
349
349
|
}
|
|
350
|
-
config.
|
|
350
|
+
config.contextChecksFromBridges.push({
|
|
351
|
+
'bridge.id': bridge.id,
|
|
352
|
+
'bridge.check': bridge.check,
|
|
351
353
|
match: ({context}) => context.marker == bridge.id,
|
|
352
354
|
exported: true,
|
|
353
355
|
apply: ({context}) => bridge.check,
|
|
354
356
|
})
|
|
355
357
|
}
|
|
358
|
+
|
|
356
359
|
if (bridge.after) {
|
|
357
360
|
for (let before of bridge.after) {
|
|
358
361
|
if (typeof before === 'string') {
|
|
@@ -402,11 +405,15 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
|
|
402
405
|
if (bridge.generatorp) {
|
|
403
406
|
const match = bridge.generatorp.match || (() => true)
|
|
404
407
|
const apply = typeof bridge.generatorp === 'function' ? bridge.generatorp : bridge.generatorp.apply || bridge.generatorp
|
|
405
|
-
|
|
408
|
+
let level = bridge.generatorp.level >= 0 ? bridge.generatorp.level : bridge.level + 1
|
|
409
|
+
if (!bridge.bridge) {
|
|
410
|
+
level = 0
|
|
411
|
+
}
|
|
406
412
|
|
|
407
413
|
const generator = {
|
|
408
414
|
where: bridge.generatorp.where || bridge.where || helpers.where(4),
|
|
409
|
-
match: async (args) => bridge.id === args.context.marker && args.context.level === level && args.context.paraphrase && await match(args),
|
|
415
|
+
// match: async (args) => bridge.id === args.context.marker && args.context.level === level && args.context.paraphrase && await match(args),
|
|
416
|
+
match: async (args) => args.isA(args.context.marker, bridge.id) && args.context.level === level && args.context.paraphrase && await match(args),
|
|
410
417
|
apply: (args) => apply(args),
|
|
411
418
|
applyWrapped: apply,
|
|
412
419
|
property: 'generatorp'
|
|
@@ -423,7 +430,8 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
|
|
423
430
|
const level = bridge.generatorr.level >= 0 ? bridge.generatorr.level : bridge.level + 1
|
|
424
431
|
const generator = {
|
|
425
432
|
where: bridge.generatorr.where || bridge.where || helpers.where(4),
|
|
426
|
-
match: async (args) => bridge.id === args.context.marker && args.context.level === level && !args.context.paraphrase && (args.context.response || args.context.isResponse) && await match(args),
|
|
433
|
+
// match: async (args) => bridge.id === args.context.marker && args.context.level === level && !args.context.paraphrase && (args.context.response || args.context.isResponse) && await match(args),
|
|
434
|
+
match: async (args) => args.isA(args.context.marker, bridge.id) && args.context.level === level && !args.context.paraphrase && (args.context.response || args.context.isResponse) && await match(args),
|
|
427
435
|
apply: (args) => apply(args),
|
|
428
436
|
applyWrapped: apply,
|
|
429
437
|
property: 'generatorr'
|
|
@@ -510,8 +518,43 @@ const handleCalculatedProps = (baseConfig, moreConfig, { addFirst, uuid } = {})
|
|
|
510
518
|
if (moreConfig.bridges) {
|
|
511
519
|
moreConfig.bridges = moreConfig.bridges.map((bridge) => {
|
|
512
520
|
bridge = { ...bridge }
|
|
513
|
-
const valid = [
|
|
514
|
-
'
|
|
521
|
+
const valid = [
|
|
522
|
+
'after',
|
|
523
|
+
'associations',
|
|
524
|
+
'before',
|
|
525
|
+
'bridge',
|
|
526
|
+
'check',
|
|
527
|
+
'children',
|
|
528
|
+
'conditional',
|
|
529
|
+
'convolution',
|
|
530
|
+
'disabled',
|
|
531
|
+
'enhanced_associations',
|
|
532
|
+
'evaluator',
|
|
533
|
+
'evaluators',
|
|
534
|
+
'generatorp',
|
|
535
|
+
'generatorpr',
|
|
536
|
+
'generatorr',
|
|
537
|
+
'generators',
|
|
538
|
+
'id',
|
|
539
|
+
'inverted',
|
|
540
|
+
'isA',
|
|
541
|
+
'level',
|
|
542
|
+
'levelSpecificHierarchy',
|
|
543
|
+
'localHierarchy',
|
|
544
|
+
'operator',
|
|
545
|
+
'optional',
|
|
546
|
+
'parents',
|
|
547
|
+
'return_type_selector',
|
|
548
|
+
'scope',
|
|
549
|
+
'selector',
|
|
550
|
+
'semantic',
|
|
551
|
+
'semantics',
|
|
552
|
+
'separators',
|
|
553
|
+
'skipable',
|
|
554
|
+
'uuid',
|
|
555
|
+
'where',
|
|
556
|
+
'words', /Bridge$/,
|
|
557
|
+
]
|
|
515
558
|
helpers.validProps(valid, bridge, 'bridge')
|
|
516
559
|
handleBridgeProps(baseConfig, bridge, { addFirst, uuid })
|
|
517
560
|
return bridge
|
|
@@ -674,7 +717,7 @@ function setWordsUUIDs (words, uuid) {
|
|
|
674
717
|
for (const key in literals) {
|
|
675
718
|
literals[key] = literals[key].map((o) => Object.assign(o, { uuid }))
|
|
676
719
|
}
|
|
677
|
-
const patterns = words.patterns
|
|
720
|
+
const patterns = words.patterns || []
|
|
678
721
|
for (const pattern of patterns) {
|
|
679
722
|
pattern.defs.map((def) => Object.assign(def, { uuid }))
|
|
680
723
|
}
|
|
@@ -903,6 +946,10 @@ class Config {
|
|
|
903
946
|
return config_toServer(config)
|
|
904
947
|
}
|
|
905
948
|
|
|
949
|
+
async run(handler) {
|
|
950
|
+
return configHelpers.run(this, handler)
|
|
951
|
+
}
|
|
952
|
+
|
|
906
953
|
async fixtures () {
|
|
907
954
|
if (this.testConfig?.fixtures) {
|
|
908
955
|
const args = {}
|
|
@@ -936,6 +983,7 @@ class Config {
|
|
|
936
983
|
|
|
937
984
|
getPseudoConfig (uuid, config) {
|
|
938
985
|
return {
|
|
986
|
+
pseudo: true,
|
|
939
987
|
description: 'this is a pseudo config that has limited functionality due to being available in the initializer and fixtures function context',
|
|
940
988
|
addAssociation: (...args) => this.addAssociation(...args),
|
|
941
989
|
addAssociations: (...args) => this.addAssociations(...args),
|
|
@@ -949,6 +997,22 @@ class Config {
|
|
|
949
997
|
removeSemantic: (...args) => this.removeSemantic(...args, uuid, config.name),
|
|
950
998
|
addWord: (...args) => this.addWord(...args, uuid),
|
|
951
999
|
addPattern: (...args) => this.addPattern(...args, uuid),
|
|
1000
|
+
updateBridge: (...args) => this.updateBridge(...args),
|
|
1001
|
+
processContext: (...args) => this.processContext(...args),
|
|
1002
|
+
|
|
1003
|
+
semantics: () => this.config.semantics,
|
|
1004
|
+
getConfigs: () => this.configs,
|
|
1005
|
+
getTestConfig: () => this.getTestConfig(),
|
|
1006
|
+
getTests: () => this.getTests(),
|
|
1007
|
+
getName: () => this.getName(),
|
|
1008
|
+
getDescription: () => this.getDescription(),
|
|
1009
|
+
getDebug: () => this.getDebug(),
|
|
1010
|
+
getDebugLoops: () => this.getDebugLoops(),
|
|
1011
|
+
getMaxDepth: () => this.getMaxDepth(),
|
|
1012
|
+
getAPIs: (...args) => this.getAPIs(...args),
|
|
1013
|
+
getAPI: (...args) => this.getAPI(...args),
|
|
1014
|
+
getUUID: (...args) => this.getUUID(...args),
|
|
1015
|
+
nsToString: (...args) => this.nsToString(...args),
|
|
952
1016
|
|
|
953
1017
|
getHierarchy: (...args) => this.config.hierarchy,
|
|
954
1018
|
getBridges: (...args) => this.config.bridges,
|
|
@@ -958,10 +1022,53 @@ class Config {
|
|
|
958
1022
|
fragment: (...args) => this.fragment(...args),
|
|
959
1023
|
server: (...args) => this.server(...args),
|
|
960
1024
|
exists: (...args) => this.exists(...args),
|
|
961
|
-
addAPI: (...args) => this.addAPI(...args)
|
|
1025
|
+
addAPI: (...args) => this.addAPI(...args),
|
|
1026
|
+
|
|
1027
|
+
getParenthesized: () => this.getParenthesized(),
|
|
1028
|
+
setParenthesized: (...args) => this.setParenthesized(...args),
|
|
962
1029
|
}
|
|
963
1030
|
}
|
|
964
1031
|
|
|
1032
|
+
getUUID() {
|
|
1033
|
+
return this.uuid
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
getTestConfig() {
|
|
1037
|
+
return this.testConfig
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
getMaxDepth() {
|
|
1041
|
+
return this.config.maxDepth
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
getDebug() {
|
|
1045
|
+
return this.config.debug
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
getDebugLoops() {
|
|
1049
|
+
return this.config.debugLoops
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
getName() {
|
|
1053
|
+
return this.name
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
getDescription() {
|
|
1057
|
+
return this.description
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
getTests() {
|
|
1061
|
+
return this.tests
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
getParenthesized(value) {
|
|
1065
|
+
return this.parenthesized
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
setParenthesized(value) {
|
|
1069
|
+
this.parenthesized = value
|
|
1070
|
+
}
|
|
1071
|
+
|
|
965
1072
|
inDevelopmentMode (call) {
|
|
966
1073
|
config.developmentModeOn += 1
|
|
967
1074
|
try {
|
|
@@ -978,7 +1085,27 @@ class Config {
|
|
|
978
1085
|
}
|
|
979
1086
|
|
|
980
1087
|
setTestConfig (testConfig) {
|
|
981
|
-
this.testConfig = testConfig
|
|
1088
|
+
this.testConfig = { ...testConfig }
|
|
1089
|
+
if (!this.testConfig.checks) {
|
|
1090
|
+
this.testConfig.checks = {}
|
|
1091
|
+
}
|
|
1092
|
+
if (!this.testConfig?.checks?.context) {
|
|
1093
|
+
this.testConfig.checks.context = []
|
|
1094
|
+
}
|
|
1095
|
+
this.testConfig.checks.context = this.contextChecksFromBridges.concat(this.testConfig.checks.context)
|
|
1096
|
+
/*
|
|
1097
|
+
const currentTestConfig = testConfig // add bridge has added check.context's
|
|
1098
|
+
|
|
1099
|
+
if (!this.testConfig.checks) {
|
|
1100
|
+
debugger
|
|
1101
|
+
// this.testConfig.checks =
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
// set during bridge setup
|
|
1105
|
+
if (currentTestConfig.checks?.context) {
|
|
1106
|
+
this.testConfig.checks.context = currentTestConfig.checks.context.concat(this.testConfig.checks.context)
|
|
1107
|
+
}
|
|
1108
|
+
*/
|
|
982
1109
|
}
|
|
983
1110
|
|
|
984
1111
|
getTestConfig () {
|
|
@@ -1108,26 +1235,52 @@ class Config {
|
|
|
1108
1235
|
return instance
|
|
1109
1236
|
}
|
|
1110
1237
|
|
|
1111
|
-
|
|
1238
|
+
getFragment(query) {
|
|
1112
1239
|
for (const instance of (this.instances || [])) {
|
|
1113
1240
|
for (const fragment of (instance.fragments || [])) {
|
|
1114
1241
|
if (fragment.query === query) {
|
|
1115
|
-
return
|
|
1242
|
+
return fragment
|
|
1116
1243
|
}
|
|
1117
1244
|
}
|
|
1118
1245
|
for (const fragment of (instance.resultss || [])) {
|
|
1119
1246
|
if (fragment.isFragment && fragment.query === query) {
|
|
1120
|
-
return
|
|
1247
|
+
return fragment
|
|
1121
1248
|
}
|
|
1122
1249
|
}
|
|
1123
1250
|
for (const fragment of (this.fragmentsBeingBuilt || [])) {
|
|
1124
1251
|
if (fragment.query === query) {
|
|
1125
|
-
return
|
|
1252
|
+
return fragment
|
|
1126
1253
|
}
|
|
1127
1254
|
}
|
|
1128
1255
|
}
|
|
1129
1256
|
}
|
|
1130
1257
|
|
|
1258
|
+
// mappings are optional
|
|
1259
|
+
async fragment (args, query, mappings) {
|
|
1260
|
+
const fragment = this.getFragment(query)
|
|
1261
|
+
if (fragment) {
|
|
1262
|
+
let fi = fragmentInstantiator(args, fragment.contexts)
|
|
1263
|
+
if (mappings) {
|
|
1264
|
+
fi = await fi
|
|
1265
|
+
return fi.instantiate([{
|
|
1266
|
+
match: ({context}) => !!mappings[context.value], // is the value in the mappings
|
|
1267
|
+
apply: ({context}) => Object.assign(context, mappings[context.value]),
|
|
1268
|
+
}])
|
|
1269
|
+
} else {
|
|
1270
|
+
return fi
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
fragmentMapper (args, values, fromModelQuery, toModelQuery) {
|
|
1276
|
+
const fromModelFragment = this.getFragment(fromModelQuery)
|
|
1277
|
+
console.dir(fromModelFragment)
|
|
1278
|
+
const toModelFragment = this.getFragment(toModelQuery)
|
|
1279
|
+
console.dir(toModelFragment)
|
|
1280
|
+
const mapper = fragmentMapperInstantiator(values, fromModelFragment.contexts, toModelFragment.contexts)
|
|
1281
|
+
return mapper
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1131
1284
|
// { rebuild: false, isModule: false }
|
|
1132
1285
|
needsRebuild (template, instance, options) {
|
|
1133
1286
|
if (options.rebuild) {
|
|
@@ -1486,6 +1639,11 @@ class Config {
|
|
|
1486
1639
|
}
|
|
1487
1640
|
}
|
|
1488
1641
|
|
|
1642
|
+
updateBridge(id, updater) {
|
|
1643
|
+
const bridge = this.config.bridges.find((b) => b.id === id)
|
|
1644
|
+
updater({ config: this, bridge })
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1489
1647
|
addBridge (bridge, uuid) {
|
|
1490
1648
|
if (!this.config.bridges) {
|
|
1491
1649
|
this.config.bridges = []
|
|
@@ -1670,7 +1828,9 @@ class Config {
|
|
|
1670
1828
|
|
|
1671
1829
|
getAPIs (uuid) {
|
|
1672
1830
|
let config
|
|
1673
|
-
if (
|
|
1831
|
+
if (!uuid) {
|
|
1832
|
+
config = this
|
|
1833
|
+
} else if (this._uuid === uuid) {
|
|
1674
1834
|
config = this
|
|
1675
1835
|
} else {
|
|
1676
1836
|
for (const km of this.configs) {
|
|
@@ -1685,6 +1845,14 @@ class Config {
|
|
|
1685
1845
|
}
|
|
1686
1846
|
}
|
|
1687
1847
|
|
|
1848
|
+
/*
|
|
1849
|
+
getAPIs (config) {
|
|
1850
|
+
if (config && config._api && config._api.multiApi) {
|
|
1851
|
+
return config._api.apis
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
*/
|
|
1855
|
+
|
|
1688
1856
|
getServer () {
|
|
1689
1857
|
return this._server
|
|
1690
1858
|
}
|
|
@@ -1787,7 +1955,7 @@ class Config {
|
|
|
1787
1955
|
|
|
1788
1956
|
// set the args in the api's
|
|
1789
1957
|
setArgs (args) {
|
|
1790
|
-
const
|
|
1958
|
+
const setConfigArgs = (config) => {
|
|
1791
1959
|
if (!config._api) {
|
|
1792
1960
|
return
|
|
1793
1961
|
}
|
|
@@ -1800,10 +1968,10 @@ class Config {
|
|
|
1800
1968
|
}
|
|
1801
1969
|
}
|
|
1802
1970
|
|
|
1803
|
-
|
|
1971
|
+
setConfigArgs(this)
|
|
1804
1972
|
for (const config of this.configs) {
|
|
1805
1973
|
if (config.config instanceof Config) {
|
|
1806
|
-
|
|
1974
|
+
setConfigArgs(config.config)
|
|
1807
1975
|
}
|
|
1808
1976
|
}
|
|
1809
1977
|
}
|
|
@@ -1832,6 +2000,16 @@ class Config {
|
|
|
1832
2000
|
}
|
|
1833
2001
|
}
|
|
1834
2002
|
|
|
2003
|
+
getObjects () {
|
|
2004
|
+
const configs = {}
|
|
2005
|
+
const ns = this.config.objects.namespaced
|
|
2006
|
+
configs[this.name] = this
|
|
2007
|
+
for (const config of this.configs) {
|
|
2008
|
+
configs[config._name] = ns[config._uuid]
|
|
2009
|
+
}
|
|
2010
|
+
return configs
|
|
2011
|
+
}
|
|
2012
|
+
|
|
1835
2013
|
getConfig (name) {
|
|
1836
2014
|
if (this.name === name) {
|
|
1837
2015
|
return this
|
|
@@ -1879,14 +2057,6 @@ class Config {
|
|
|
1879
2057
|
} else if (this.scope == 'development') {
|
|
1880
2058
|
new_result = !(element.scope === 'testing')
|
|
1881
2059
|
}
|
|
1882
|
-
/*
|
|
1883
|
-
if (global.GORDO && old_result !== new_result) {
|
|
1884
|
-
global.GORDO = false
|
|
1885
|
-
console.log("THERE WAS A DIFFERENCE ------------------------------------------------")
|
|
1886
|
-
debugger // greg23old
|
|
1887
|
-
}
|
|
1888
|
-
*/
|
|
1889
|
-
// return old_result
|
|
1890
2060
|
return new_result
|
|
1891
2061
|
}
|
|
1892
2062
|
|
|
@@ -1992,6 +2162,8 @@ class Config {
|
|
|
1992
2162
|
config.priorities = config.priorities || []
|
|
1993
2163
|
}
|
|
1994
2164
|
|
|
2165
|
+
this.contextChecksFromBridges = []
|
|
2166
|
+
|
|
1995
2167
|
this._enable = []
|
|
1996
2168
|
this._apiKMs = apiKMs
|
|
1997
2169
|
|
|
@@ -2051,7 +2223,7 @@ class Config {
|
|
|
2051
2223
|
|
|
2052
2224
|
// set the default server so stuff just works
|
|
2053
2225
|
// this.server('https://184.67.27.82:3000', '6804954f-e56d-471f-bbb8-08e3c54d9321')
|
|
2054
|
-
this.server('https://thinktelligence.com
|
|
2226
|
+
this.server('https://thinktelligence.com/entodicton', '6804954f-e56d-471f-bbb8-08e3c54d9321')
|
|
2055
2227
|
|
|
2056
2228
|
this.defaultConfig()
|
|
2057
2229
|
this.initializerFn = ({ currentConfig }) => {
|
|
@@ -2318,6 +2490,7 @@ class Config {
|
|
|
2318
2490
|
// update uuid here set the uuid in the objects and add error checking
|
|
2319
2491
|
cp.initializerFn = this.initializerFn
|
|
2320
2492
|
cp.terminatorFn = this.terminatorFn
|
|
2493
|
+
cp.contextChecksFromBridges = this.contextChecksFromBridges
|
|
2321
2494
|
cp._apiKMs = this._apiKMs
|
|
2322
2495
|
cp._apiConstructor = this._apiConstructor
|
|
2323
2496
|
if (cp._apiConstructor) {
|
|
@@ -2678,19 +2851,37 @@ class Config {
|
|
|
2678
2851
|
|
|
2679
2852
|
getContextChecks() {
|
|
2680
2853
|
const allChecks = []
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
for (const
|
|
2684
|
-
|
|
2685
|
-
|
|
2854
|
+
let defaults = () => []
|
|
2855
|
+
if (this.loadOrdering) {
|
|
2856
|
+
for (const name of this.loadOrdering) {
|
|
2857
|
+
const checks = this.kms[name].testConfig?.checks?.context || []
|
|
2858
|
+
const oldDefaults = defaults
|
|
2859
|
+
for (const check of checks) {
|
|
2860
|
+
if (!check.match) {
|
|
2861
|
+
const oldDefaults = defaults
|
|
2862
|
+
defaults = () => helpers.safeNoDups([...check.apply(), ...oldDefaults()])
|
|
2863
|
+
continue
|
|
2864
|
+
}
|
|
2865
|
+
if (check.exported) {
|
|
2866
|
+
allChecks.push(check)
|
|
2867
|
+
}
|
|
2686
2868
|
}
|
|
2687
2869
|
}
|
|
2688
2870
|
}
|
|
2689
2871
|
for (const check of this.testConfig?.checks?.context || []) {
|
|
2872
|
+
if (!check.match) {
|
|
2873
|
+
const oldDefaults = defaults
|
|
2874
|
+
defaults = () => [...new Set([...check.apply(), ...oldDefaults()])]
|
|
2875
|
+
continue
|
|
2876
|
+
}
|
|
2690
2877
|
if (!check.exported) {
|
|
2691
2878
|
allChecks.push(check)
|
|
2692
2879
|
}
|
|
2693
2880
|
}
|
|
2881
|
+
allChecks.push({
|
|
2882
|
+
match: () => true,
|
|
2883
|
+
apply: defaults
|
|
2884
|
+
})
|
|
2694
2885
|
return allChecks
|
|
2695
2886
|
}
|
|
2696
2887
|
|
package/src/configHelpers.js
CHANGED
|
@@ -97,11 +97,11 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
|
97
97
|
if (args.uuid) {
|
|
98
98
|
args.objects = args.getObjects(args.uuid)
|
|
99
99
|
}
|
|
100
|
-
if (!hierarchy) {
|
|
101
|
-
hierarchy = config.
|
|
100
|
+
if (!hierarchy && config.getHierarchy) {
|
|
101
|
+
hierarchy = config.getHierarchy()
|
|
102
102
|
}
|
|
103
103
|
// callId
|
|
104
|
-
args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.
|
|
104
|
+
args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.getName()}` : config.getName())
|
|
105
105
|
if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
|
|
106
106
|
args.calls = new InitCalls(Object.keys(global.theprogrammablemind.loadForTesting)[0])
|
|
107
107
|
}
|
|
@@ -112,14 +112,18 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
|
112
112
|
throw new ErrorReason(context)
|
|
113
113
|
}
|
|
114
114
|
args.kms = config.getConfigs()
|
|
115
|
-
args.config = config
|
|
115
|
+
args.config = config.getPseudoConfig(uuidForScoping, config)
|
|
116
116
|
args.hierarchy = hierarchy
|
|
117
117
|
args.isA = isA(hierarchy)
|
|
118
118
|
// args.listable = listable(hierarchy)
|
|
119
119
|
// args.asList = asList
|
|
120
120
|
args.retry = () => { throw new RetryError() }
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
// mappings are optional
|
|
122
|
+
args.fragments = (query, mappings) => {
|
|
123
|
+
return config.fragment(args, query, mappings)
|
|
124
|
+
}
|
|
125
|
+
args.fragmentMapper = (values, fromModelQuery, toModelQuery) => {
|
|
126
|
+
return config.fragmentMapper(args, values, fromModelQuery, toModelQuery)
|
|
123
127
|
}
|
|
124
128
|
args.breakOnSemantics = false
|
|
125
129
|
args.theDebugger = {
|
|
@@ -133,23 +137,35 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
|
133
137
|
args.addPattern = (pattern, def) => config.addPattern(pattern, args.uuid)
|
|
134
138
|
args.addGenerator = (generator) => config.addGenerator(generator, args.uuid, config.name)
|
|
135
139
|
|
|
136
|
-
if (config.
|
|
137
|
-
args.testModuleName = config.
|
|
140
|
+
if (config.getTestConfig()?.testModuleName) {
|
|
141
|
+
args.testModuleName = config.getTestConfig().testModuleName
|
|
138
142
|
}
|
|
139
143
|
args.addAssumedScoped = (args, assumed) => {
|
|
140
144
|
const addAssumed = (args, ...moreAssumed) => {
|
|
141
145
|
return { ...args, assumed: Object.assign({}, assumed, (args.assumed || {}), ...moreAssumed) }
|
|
142
146
|
}
|
|
143
147
|
|
|
144
|
-
args.s = (c) => config.getSemantics(logs).apply(args, c)
|
|
145
|
-
args.g = (c,
|
|
146
|
-
|
|
148
|
+
args.s = (c, options = {}) => config.getSemantics(logs).apply(args, c, options)
|
|
149
|
+
args.g = (c, rest = {}) => {
|
|
150
|
+
// if (JSON.stringify(rest) !== '{}' && !(rest.assumed || rest.options)) {
|
|
151
|
+
// debugger
|
|
152
|
+
// }
|
|
153
|
+
const { assumed = {}, options = {} } = rest
|
|
154
|
+
return config.getGenerators(logs).apply(addAssumed(args, assumed), c, assumed, options)
|
|
147
155
|
}
|
|
148
|
-
args.gp = (c,
|
|
149
|
-
|
|
156
|
+
args.gp = (c, rest = {}) => {
|
|
157
|
+
// if (JSON.stringify(rest) !== '{}' && !(rest.assumed || rest.options)) {
|
|
158
|
+
// debugger
|
|
159
|
+
// }
|
|
160
|
+
const { assumed = {}, options = {} } = rest
|
|
161
|
+
return config.getGenerators(logs).apply(addAssumed(args, assumed, { paraphrase: true, isResponse: false, response: false }), c, { paraphrase: true, isResponse: false, response: false }, options)
|
|
150
162
|
}
|
|
151
|
-
args.gr = (c,
|
|
152
|
-
|
|
163
|
+
args.gr = (c, rest = {}) => {
|
|
164
|
+
// if (JSON.stringify(rest) !== '{}' && !(rest.assumed || rest.options)) {
|
|
165
|
+
// debugger
|
|
166
|
+
// }
|
|
167
|
+
const { assumed = {}, options = {} } = rest
|
|
168
|
+
return config.getGenerators(logs).apply(addAssumed(args, assumed, { paraphrase: false, isResponse: true }), { ...c, paraphrase: false, isResponse: true }, options)
|
|
153
169
|
}
|
|
154
170
|
args.e = (c) => {
|
|
155
171
|
if (!c) {
|
|
@@ -182,14 +198,8 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
|
182
198
|
}
|
|
183
199
|
config.getAddedArgs(args)
|
|
184
200
|
|
|
185
|
-
Object.assign(args, args.getUUIDScoped(uuidForScoping || config.
|
|
201
|
+
Object.assign(args, args.getUUIDScoped(uuidForScoping || config.getUUID()))
|
|
186
202
|
args.apis = args.apis || ((name) => config.getConfig(name).api)
|
|
187
|
-
/*
|
|
188
|
-
if (uuidForScoping) {
|
|
189
|
-
Object.assign(args, args.getUUIDScoped(uuidForScoping))
|
|
190
|
-
}
|
|
191
|
-
*/
|
|
192
|
-
// sets args for all the API. that make a copy so the args must be fully setup by here except for scoped
|
|
193
203
|
config.setArgs(args)
|
|
194
204
|
}
|
|
195
205
|
|
|
@@ -202,6 +212,22 @@ const getObjects = (objects) => {
|
|
|
202
212
|
}
|
|
203
213
|
}
|
|
204
214
|
|
|
215
|
+
const run = async (config, handler) => {
|
|
216
|
+
// map to hash
|
|
217
|
+
config = config || {}
|
|
218
|
+
if (config.config) {
|
|
219
|
+
config = config
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const hierarchy = new DigraphInternal((config.config || {}).hierarchy || [])
|
|
223
|
+
|
|
224
|
+
const objects = config.config.objects.namespaced[config.uuid]
|
|
225
|
+
const logs = []
|
|
226
|
+
const args = {}
|
|
227
|
+
setupArgs(args, config, logs, hierarchy)
|
|
228
|
+
return handler(args)
|
|
229
|
+
}
|
|
230
|
+
|
|
205
231
|
const processContext = async (context, { objects = {}, config, logs = [] }) => {
|
|
206
232
|
const generators = config.getGenerators(logs)
|
|
207
233
|
const semantics = config.getSemantics(logs)
|
|
@@ -373,21 +399,21 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
|
|
|
373
399
|
const generated = contextPrime.isResponse ? await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed) : ''
|
|
374
400
|
let generatedParenthesized = []
|
|
375
401
|
if (generateParenthesized) {
|
|
376
|
-
config.
|
|
402
|
+
config.setParenthesized(true)
|
|
377
403
|
generatedParenthesized = contextPrime.isResponse ? await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed) : ''
|
|
378
|
-
config.
|
|
404
|
+
config.setParenthesized(false)
|
|
379
405
|
}
|
|
380
406
|
// assumed = { paraphrase: true, response: false };
|
|
381
407
|
assumed = { paraphrase: true, isResponse: false, response: false }
|
|
382
408
|
if (generateParenthesized) {
|
|
383
|
-
config.
|
|
409
|
+
config.setParenthesized(false)
|
|
384
410
|
}
|
|
385
411
|
const paraphrases = await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed)
|
|
386
412
|
let paraphrasesParenthesized = []
|
|
387
413
|
if (generateParenthesized) {
|
|
388
|
-
config.
|
|
414
|
+
config.setParenthesized(true)
|
|
389
415
|
paraphrasesParenthesized = await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed)
|
|
390
|
-
config.
|
|
416
|
+
config.setParenthesized(false)
|
|
391
417
|
}
|
|
392
418
|
contextsPrime.push(contextPrime)
|
|
393
419
|
generatedPrime.push(generated)
|
|
@@ -434,11 +460,6 @@ const loadInstance = async (config, instance) => {
|
|
|
434
460
|
const transitoryMode = global.transitoryMode
|
|
435
461
|
global.transitoryMode = false
|
|
436
462
|
|
|
437
|
-
/*
|
|
438
|
-
if (config.name == 'people' && instance.name == 'people') {
|
|
439
|
-
debugger
|
|
440
|
-
}
|
|
441
|
-
*/
|
|
442
463
|
const rl = instance.resultss.length
|
|
443
464
|
if (rl > 0) {
|
|
444
465
|
config.addAssociations(instance.resultss[instance.resultss.length - 1].rtf_associations || [])
|
|
@@ -516,6 +537,7 @@ module.exports = {
|
|
|
516
537
|
// listable,
|
|
517
538
|
setupArgs,
|
|
518
539
|
processContext,
|
|
540
|
+
run,
|
|
519
541
|
getObjects,
|
|
520
542
|
gs,
|
|
521
543
|
processContextsB,
|
package/src/fragments.js
CHANGED
|
@@ -1,85 +1,42 @@
|
|
|
1
1
|
const _ = require('lodash')
|
|
2
2
|
const helpers = require('./helpers')
|
|
3
3
|
|
|
4
|
-
function fragmentInstantiator(args, contexts) {
|
|
5
|
-
return new Object({
|
|
6
|
-
contexts: () =>
|
|
7
|
-
|
|
4
|
+
function fragmentInstantiator (args, contexts) {
|
|
5
|
+
return new Object({
|
|
6
|
+
contexts: () => {
|
|
7
|
+
return _.cloneDeep(contexts)
|
|
8
|
+
},
|
|
8
9
|
instantiate: async (mappings) => {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const visited = new WeakSet();
|
|
13
|
-
|
|
14
|
-
// Stack item: { node, path }
|
|
15
|
-
// path is an array like: [], ['user'], ['users', 0], ['users', 0, 'address']
|
|
16
|
-
const todo = [{ node: root, path: [] }];
|
|
17
|
-
|
|
18
|
-
args = { ...args };
|
|
19
|
-
|
|
10
|
+
const instantiated = _.cloneDeep(contexts)
|
|
11
|
+
const todo = [{ context: instantiated, path: [] }]
|
|
12
|
+
args = { ...args }
|
|
20
13
|
while (todo.length > 0) {
|
|
21
|
-
const {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (!helpers.isCompound(node)) continue;
|
|
25
|
-
|
|
26
|
-
// Prevent reprocessing (including circular refs)
|
|
27
|
-
if (visited.has(node)) continue;
|
|
28
|
-
visited.add(node);
|
|
29
|
-
|
|
30
|
-
// Attach clean, frozen path array (non-enumerable)
|
|
31
|
-
Object.defineProperty(node, '__path', {
|
|
32
|
-
value: Object.freeze(path.slice()), // immutable copy
|
|
33
|
-
writable: false,
|
|
34
|
-
enumerable: false,
|
|
35
|
-
configurable: false
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// Helpful string version
|
|
39
|
-
Object.defineProperty(node, '__pathString', {
|
|
40
|
-
value: path.map(p => String(p)).join('.'),
|
|
41
|
-
enumerable: false
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// Pass rich context to mappings
|
|
45
|
-
args.context = node;
|
|
46
|
-
args.path = path; // e.g. ['users', 0, 'profile']
|
|
47
|
-
args.pathString = path.map(p => String(p)).join('.'); // "users.0.profile"
|
|
48
|
-
|
|
49
|
-
// Apply mappings
|
|
14
|
+
const { context, path } = todo.pop()
|
|
15
|
+
args.context = context
|
|
16
|
+
args.path = path
|
|
50
17
|
for (const mapping of mappings) {
|
|
51
18
|
if (await mapping.match(args)) {
|
|
52
|
-
await mapping.apply(args)
|
|
19
|
+
await mapping.apply(args)
|
|
53
20
|
}
|
|
54
21
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (helpers.isCompound(child)) {
|
|
60
|
-
todo.push({
|
|
61
|
-
node: child,
|
|
62
|
-
path: [...path, index] // index as number!
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
} else {
|
|
67
|
-
// Plain object
|
|
68
|
-
for (const key of Object.keys(node)) {
|
|
69
|
-
const child = node[key];
|
|
70
|
-
if (helpers.isCompound(child)) {
|
|
71
|
-
todo.push({
|
|
72
|
-
node: child,
|
|
73
|
-
path: [...path, key] // key as string
|
|
74
|
-
});
|
|
75
|
-
}
|
|
22
|
+
for (const key of Object.keys(context)) {
|
|
23
|
+
// if (['number', 'string', 'boolean'].includes(typeof (context[key]))) {
|
|
24
|
+
if (!helpers.isCompound(context[key])) {
|
|
25
|
+
continue
|
|
76
26
|
}
|
|
27
|
+
if (context[key].instantiated) {
|
|
28
|
+
continue
|
|
29
|
+
}
|
|
30
|
+
todo.push({ context: context[key], path: [...path, key] })
|
|
77
31
|
}
|
|
78
32
|
}
|
|
79
|
-
|
|
80
|
-
|
|
33
|
+
if (contexts.length == 1 && instantiated.length == 1) {
|
|
34
|
+
return instantiated[0]
|
|
35
|
+
} else {
|
|
36
|
+
return instantiated
|
|
37
|
+
}
|
|
81
38
|
}
|
|
82
|
-
})
|
|
39
|
+
})
|
|
83
40
|
}
|
|
84
41
|
|
|
85
42
|
async function fragmentMapperInstantiator(values, modelFrom, modelTo) {
|
package/src/generators.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const { stringify } = require('flatted');
|
|
2
1
|
const { args: contextArgs, normalizeGenerator } = require('./helpers')
|
|
3
2
|
const Lines = require('../lines')
|
|
4
3
|
const helpers = require('./helpers')
|
|
@@ -27,11 +26,13 @@ class Generator {
|
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
|
|
29
|
+
/*
|
|
30
30
|
getAPIs (config) {
|
|
31
31
|
if (config && config._api && config._api.multiApi) {
|
|
32
32
|
return config._api.apis
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
+
*/
|
|
35
36
|
|
|
36
37
|
toLabel () {
|
|
37
38
|
const where = this.where ? `where: "${this.where}"` : ''
|
|
@@ -60,7 +61,7 @@ class Generator {
|
|
|
60
61
|
context,
|
|
61
62
|
callId,
|
|
62
63
|
api: this.getAPI(config),
|
|
63
|
-
apis:
|
|
64
|
+
apis: config.getAPIs(),
|
|
64
65
|
}
|
|
65
66
|
const args = Object.assign({}, baseArgs, moreArgs, (baseArgs.getUUIDScoped || (() => { return {} }))(this.uuid))
|
|
66
67
|
// return this.match(args)
|
|
@@ -79,11 +80,11 @@ class Generator {
|
|
|
79
80
|
if (!log) {
|
|
80
81
|
throw new Error('generators.apply argument log is required')
|
|
81
82
|
}
|
|
82
|
-
if (baseArgs.call && config && baseArgs.calls.stack.length > config.
|
|
83
|
-
throw new Error(`Max depth of ${config.
|
|
83
|
+
if (baseArgs.call && config && baseArgs.calls.stack.length > config.getMaxDepth()) {
|
|
84
|
+
throw new Error(`Max depth of ${config.getMaxDepth()} for calls has been exceeded. maxDepth can be set on the config object. To see the calls run with the --dl or set the debugLoops property on the config`)
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
if (config && config.
|
|
87
|
+
if (config && config.getDebugLoops()) {
|
|
87
88
|
console.log('apply', this.toLabel())
|
|
88
89
|
}
|
|
89
90
|
// this.getAPI(config)
|
|
@@ -114,7 +115,7 @@ class Generator {
|
|
|
114
115
|
config,
|
|
115
116
|
response,
|
|
116
117
|
api: this.getAPI(config),
|
|
117
|
-
apis:
|
|
118
|
+
apis: config.getAPIs()
|
|
118
119
|
}
|
|
119
120
|
const args = Object.assign({}, baseArgs, moreArgs, (baseArgs.getUUIDScoped || (() => { return {} }))(this.uuid))
|
|
120
121
|
if (this.property === 'generatorp') {
|
|
@@ -186,7 +187,7 @@ class Generators {
|
|
|
186
187
|
// this.logs.push(`Generators: applied ${generator.toString()}\n to\n ${stringify(context)}`)
|
|
187
188
|
let errorMessage = 'The apply function did not return a value'
|
|
188
189
|
try {
|
|
189
|
-
generated = await generator.apply(args, objects, context, hierarchy, config, response, log)
|
|
190
|
+
generated = await generator.apply(args, objects, context, hierarchy, config, response, log, options)
|
|
190
191
|
} catch (e) {
|
|
191
192
|
// the next if handle this
|
|
192
193
|
generated = null
|
|
@@ -213,7 +214,7 @@ class Generators {
|
|
|
213
214
|
lines.newRow()
|
|
214
215
|
lines.setElement(0, 1, 'TO')
|
|
215
216
|
lines.setElement(0, 2, `context_id: ${context.context_id}`)
|
|
216
|
-
lines.setElement(1, 2, stringify(helpers.sortJson(context, { depth: 10 }), null, 2))
|
|
217
|
+
lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 10 }), null, 2))
|
|
217
218
|
lines.newRow()
|
|
218
219
|
lines.setElement(0, 1, 'STACK')
|
|
219
220
|
lines.setElement(0, 2, stack)
|
|
@@ -224,13 +225,13 @@ class Generators {
|
|
|
224
225
|
lines.setElement(0, 1, 'ERROR')
|
|
225
226
|
lines.setElement(0, 2, errorMessage)
|
|
226
227
|
this.logs.push(lines.toString())
|
|
227
|
-
const message = `ERROR while applying (${source}) ${generator.toLabel()}\n to\n ${stringify(context, null, 2)}.\n${errorMessage}'`
|
|
228
|
+
const message = `ERROR while applying (${source}) ${generator.toLabel()}\n to\n ${JSON.stringify(context, null, 2)}.\n${errorMessage}'`
|
|
228
229
|
// this.logs.push(message)
|
|
229
230
|
// return [message]
|
|
230
231
|
args.calls.pop()
|
|
231
232
|
throw { error: [message], logs: this.logs }
|
|
232
233
|
}
|
|
233
|
-
if (
|
|
234
|
+
if (config.getDebug()) {
|
|
234
235
|
const widths = Lines.addRemainder([10, 10])
|
|
235
236
|
const lines = new Lines(widths)
|
|
236
237
|
lines.setElement(0, 0, 'Generator')
|
|
@@ -255,7 +256,7 @@ class Generators {
|
|
|
255
256
|
lines.newRow()
|
|
256
257
|
lines.setElement(0, 1, 'TO')
|
|
257
258
|
lines.setElement(0, 2, `context_id: ${context.context_id}`)
|
|
258
|
-
lines.setElement(1, 2, stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
|
|
259
|
+
lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
|
|
259
260
|
this.logs.push(lines.toString())
|
|
260
261
|
}
|
|
261
262
|
applied = true
|
|
@@ -263,7 +264,7 @@ class Generators {
|
|
|
263
264
|
}
|
|
264
265
|
}
|
|
265
266
|
args.calls.pop()
|
|
266
|
-
if (!applied &&
|
|
267
|
+
if (!applied && config.getDebug()) {
|
|
267
268
|
const widths = Lines.addRemainder([10, 10])
|
|
268
269
|
const lines = new Lines(widths)
|
|
269
270
|
lines.setElement(0, 0, 'Generator')
|
|
@@ -273,10 +274,14 @@ class Generators {
|
|
|
273
274
|
lines.setElement(0, 2, stack)
|
|
274
275
|
lines.newRow()
|
|
275
276
|
lines.setElement(0, 1, 'TO')
|
|
276
|
-
lines.setElement(0, 2, stringify(context, null, 2))
|
|
277
|
+
lines.setElement(0, 2, JSON.stringify(context, null, 2))
|
|
277
278
|
this.logs.push(lines.toString())
|
|
278
279
|
}
|
|
279
|
-
|
|
280
|
+
let parenthesized = false
|
|
281
|
+
if (config && config.getParenthesized()) {
|
|
282
|
+
parenthesized = true
|
|
283
|
+
}
|
|
284
|
+
return parenthesized ? '(' + generated + ')' : generated
|
|
280
285
|
}
|
|
281
286
|
}
|
|
282
287
|
|
package/src/helpers.js
CHANGED
|
@@ -292,8 +292,53 @@ const hashCode = (str) => {
|
|
|
292
292
|
return hash
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
|
|
296
|
-
|
|
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
|
@@ -1,7 +1,32 @@
|
|
|
1
|
-
function
|
|
1
|
+
function areFirstNEqual(arr1, arr2, n) {
|
|
2
|
+
if (n <= 0) return true;
|
|
3
|
+
if (arr1.length < n || arr2.length < n) return false;
|
|
4
|
+
|
|
5
|
+
for (let i = 0; i < n; i++) {
|
|
6
|
+
if (arr1[i] !== arr2[i]) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function project(source, filters, path=[]) {
|
|
2
14
|
if (['string', 'number'].includes(typeof source)) {
|
|
3
15
|
return source
|
|
4
16
|
}
|
|
17
|
+
if (Array.isArray(source)) {
|
|
18
|
+
const result = []
|
|
19
|
+
for (const value of source) {
|
|
20
|
+
result.push(project(value, filters, [...path, '*']))
|
|
21
|
+
}
|
|
22
|
+
return result
|
|
23
|
+
}
|
|
24
|
+
function isPlainObject(obj) {
|
|
25
|
+
return Object.prototype.toString.call(obj) === '[object Object]';
|
|
26
|
+
}
|
|
27
|
+
if (!isPlainObject(source) && !Array.isArray(source)) {
|
|
28
|
+
return source
|
|
29
|
+
}
|
|
5
30
|
|
|
6
31
|
if (Object.keys(source).length === 0 && filters.length === 0) {
|
|
7
32
|
return {};
|
|
@@ -11,7 +36,7 @@ function project(source, filters) {
|
|
|
11
36
|
const filter = filters.find(f => f.match({ context: source }));
|
|
12
37
|
if (!filter) {
|
|
13
38
|
if (Array.isArray(source)) {
|
|
14
|
-
return source.map((element) => project(element, filters))
|
|
39
|
+
return source.map((element) => project(element, filters, [...path, '*']))
|
|
15
40
|
}
|
|
16
41
|
return {};
|
|
17
42
|
}
|
|
@@ -22,6 +47,7 @@ function project(source, filters) {
|
|
|
22
47
|
// update
|
|
23
48
|
const updatedProperties = []
|
|
24
49
|
for (const property of properties) {
|
|
50
|
+
// property that contains a list of properties to be checked
|
|
25
51
|
if (property.properties) {
|
|
26
52
|
for (const moreProperty of source[property.properties] || []) {
|
|
27
53
|
updatedProperties.push(moreProperty)
|
|
@@ -35,10 +61,34 @@ function project(source, filters) {
|
|
|
35
61
|
// Build the result object
|
|
36
62
|
const result = {};
|
|
37
63
|
properties.forEach(prop => {
|
|
38
|
-
if (source.hasOwnProperty(prop)) {
|
|
64
|
+
if (prop.path && (prop.path.length === path.length + 1) && areFirstNEqual(path, prop.path, path.length) && source.hasOwnProperty(prop.path[path.length])) {
|
|
65
|
+
const endProp = prop.path[path.length]
|
|
66
|
+
if (Array.isArray(source[endProp])) {
|
|
67
|
+
result[endProp] = []
|
|
68
|
+
for (const key in source[endProp]) {
|
|
69
|
+
result[endProp].push(project(source[endProp][key], filters, [...path, endProp, key]))
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
result[endProp] = {}
|
|
73
|
+
for (const key in source[endProp]) {
|
|
74
|
+
result[endProp][key] = project(source[endProp][key], filters, [...path, endProp, key])
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
} else if (source.hasOwnProperty(prop)) {
|
|
39
78
|
// If the property is an object and not null, recursively project it
|
|
40
79
|
if (typeof source[prop] === 'object' && source[prop] !== null) {
|
|
41
|
-
result[prop] = project(source[prop], filters);
|
|
80
|
+
result[prop] = project(source[prop], filters, [...path, prop]);
|
|
81
|
+
} else {
|
|
82
|
+
// Copy primitive or null properties directly
|
|
83
|
+
result[prop] = source[prop];
|
|
84
|
+
}
|
|
85
|
+
} else if (prop.property && source.hasOwnProperty(prop.property)) {
|
|
86
|
+
// If the property is an object and not null, recursively project it
|
|
87
|
+
if (typeof source[prop.property] === 'object' && source[prop.property] !== null) {
|
|
88
|
+
result[prop.property] = {}
|
|
89
|
+
for (const key of prop.check) {
|
|
90
|
+
result[prop.property][key] = project(source[prop.property][key], filters, [...path, prop.property, key]);
|
|
91
|
+
}
|
|
42
92
|
} else {
|
|
43
93
|
// Copy primitive or null properties directly
|
|
44
94
|
result[prop] = source[prop];
|
package/src/semantics.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const { args: contextArgs, normalizeGenerator, normalizeSemantic } = require('./helpers')
|
|
2
2
|
const Lines = require('../lines')
|
|
3
3
|
const helpers = require('./helpers')
|
|
4
|
+
const debug = require('./debug')
|
|
4
5
|
|
|
5
6
|
class Semantic {
|
|
6
7
|
// constructor ({match, apply, uuid, index, km, notes}) {
|
|
@@ -43,11 +44,13 @@ class Semantic {
|
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
/*
|
|
46
48
|
getAPIs (config) {
|
|
47
49
|
if (config && config._api && config._api.multiApi) {
|
|
48
50
|
return config._api.apis
|
|
49
51
|
}
|
|
50
52
|
}
|
|
53
|
+
*/
|
|
51
54
|
|
|
52
55
|
fixUpArgs (args, context) {
|
|
53
56
|
args.uuid = this.uuid
|
|
@@ -57,7 +60,7 @@ class Semantic {
|
|
|
57
60
|
args.global = objects
|
|
58
61
|
const config = args.config
|
|
59
62
|
args.api = this.getAPI(config)
|
|
60
|
-
args.apis =
|
|
63
|
+
args.apis = config.getAPIs()
|
|
61
64
|
args.args = contextArgs(context, args.hierarchy)
|
|
62
65
|
args.context = context
|
|
63
66
|
let n = (id) => id
|
|
@@ -70,6 +73,7 @@ class Semantic {
|
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
async matches (args, context, options = {}) {
|
|
76
|
+
args = {...args}
|
|
73
77
|
this.fixUpArgs(args, context)
|
|
74
78
|
const matches = await this.matcher(args)
|
|
75
79
|
if (matches && (options.debug || {}).match || args.callId === this.callId) {
|
|
@@ -81,12 +85,13 @@ class Semantic {
|
|
|
81
85
|
}
|
|
82
86
|
|
|
83
87
|
async apply (args, context, s, options = {}) {
|
|
88
|
+
args = {...args}
|
|
84
89
|
const { config } = args
|
|
85
|
-
if (config && config.
|
|
90
|
+
if (config && config.getDebugLoops()) {
|
|
86
91
|
console.log('apply', this.toLabel())
|
|
87
92
|
}
|
|
88
|
-
if (args.calls && config && args.calls.stack.length > config.
|
|
89
|
-
throw new Error(`Max depth of ${config.
|
|
93
|
+
if (args.calls && config && args.calls.stack.length > config.getMaxDepth()) {
|
|
94
|
+
throw new Error(`Max depth of ${config.getMaxDepth()} for calls has been exceeded. maxDepth can be set on the config object. To see the calls run with the --dl or set the debugLoops property on the config`)
|
|
90
95
|
}
|
|
91
96
|
|
|
92
97
|
const contextPrime = Object.assign({}, context)
|
|
@@ -157,6 +162,7 @@ class Semantics {
|
|
|
157
162
|
}
|
|
158
163
|
args = { ...args }
|
|
159
164
|
const config = args.config
|
|
165
|
+
const debug = config.getDebug()
|
|
160
166
|
let contextPrime = Object.assign({}, context)
|
|
161
167
|
const s = (context, options) => this.apply(args, context, options)
|
|
162
168
|
let applied = false
|
|
@@ -197,7 +203,6 @@ class Semantics {
|
|
|
197
203
|
continue
|
|
198
204
|
}
|
|
199
205
|
if (!contextPrime.controlKeepMotivation && semantic.oneShot) {
|
|
200
|
-
// semantic.tied_ids.forEach((tied_id) => args.config.removeSemantic(tied_id))
|
|
201
206
|
args.config.removeSemantic(semantic)
|
|
202
207
|
}
|
|
203
208
|
for (const { listener } of deferred) {
|
|
@@ -247,7 +252,7 @@ class Semantics {
|
|
|
247
252
|
}
|
|
248
253
|
args.calls.touch(contextPrime)
|
|
249
254
|
// this.logs.push(`Semantics: applied ${semantic.toString()}\n to\n ${JSON.stringify(context)}\n the result was ${JSON.stringify(contextPrime)}\n`)
|
|
250
|
-
if (
|
|
255
|
+
if (config.getDebug()) {
|
|
251
256
|
const widths = Lines.addRemainder([10, 10])
|
|
252
257
|
const lines = new Lines(widths)
|
|
253
258
|
lines.setElement(0, 0, 'Semantic')
|
|
@@ -294,7 +299,7 @@ class Semantics {
|
|
|
294
299
|
counter += 1
|
|
295
300
|
}
|
|
296
301
|
args.calls.pop()
|
|
297
|
-
if (!applied &&
|
|
302
|
+
if (!applied && debug) {
|
|
298
303
|
const widths = Lines.addRemainder([10, 10])
|
|
299
304
|
const lines = new Lines(widths)
|
|
300
305
|
lines.setElement(0, 0, 'Semantic')
|