manyfest 1.0.22 → 1.0.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/.browserslistrc CHANGED
@@ -1 +1 @@
1
- since 2018
1
+ > 0.01%
@@ -5,7 +5,7 @@
5
5
 
6
6
  "LibraryOutputFolder": "./dist/",
7
7
 
8
- "LibraryUniminifiedFileName": "manyfest.js",
8
+ "LibraryUniminifiedFileName": "manyfest.compatible.js",
9
9
 
10
- "LibraryMinifiedFileName": "manyfest.min.js"
10
+ "LibraryMinifiedFileName": "manyfest.compatible.min.js"
11
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "manyfest",
3
- "version": "1.0.22",
3
+ "version": "1.0.23",
4
4
  "description": "JSON Object Manifest for Data Description and Parsing",
5
5
  "main": "source/Manyfest.js",
6
6
  "scripts": {
@@ -42,7 +42,7 @@ class ManyfestObjectAddressResolverGetValue
42
42
  }
43
43
 
44
44
  // Get the value of an element at an address
45
- getValueAtAddress (pObject, pAddress, pParentAddress)
45
+ getValueAtAddress (pObject, pAddress, pParentAddress, pRootObject)
46
46
  {
47
47
  // Make sure pObject (the object we are meant to be recursing) is an object (which could be an array or object)
48
48
  if (typeof(pObject) != 'object') return undefined;
@@ -55,9 +55,54 @@ class ManyfestObjectAddressResolverGetValue
55
55
  tmpParentAddress = pParentAddress;
56
56
  }
57
57
 
58
+ // Set the root object to the passed-in object if it isn't set yet. This is expected to be the root object.
59
+ let tmpRootObject = (typeof(pRootObject) == 'undefined') ? pObject : pRootObject;
60
+
58
61
  // TODO: Make this work for things like SomeRootObject.Metadata["Some.People.Use.Bad.Object.Property.Names"]
59
62
  let tmpSeparatorIndex = pAddress.indexOf('.');
60
63
 
64
+ // Adding simple back-navigation in objects
65
+ if (tmpSeparatorIndex == 0)
66
+ {
67
+ // Given an address of "Bundle.Contract.IDContract...Project.IDProject" the ... would be interpreted as two back-navigations from IDContract.
68
+ // When the address is passed in, though, the first . is already eliminated. So we can count the dots.
69
+ let tmpParentAddressParts = tmpParentAddress.split('.');
70
+
71
+ let tmpBackNavigationCount = 0;
72
+
73
+ // Count the number of dots
74
+ for (let i = 0; i < pAddress.length; i++)
75
+ {
76
+ if (pAddress.charAt(i) != '.')
77
+ {
78
+ break;
79
+ }
80
+ tmpBackNavigationCount++;
81
+ }
82
+
83
+ let tmpParentAddressLength = tmpParentAddressParts.length - tmpBackNavigationCount;
84
+
85
+ if (tmpParentAddressLength < 0)
86
+ {
87
+ // We are trying to back navigate more than we can.
88
+ // TODO: Should this be undefined or should we bank out at the bottom and try to go forward?
89
+ // This seems safest for now.
90
+ return undefined;
91
+ }
92
+ else
93
+ {
94
+ // We are trying to back navigate to a parent object.
95
+ // Recurse with the back-propagated parent address, and, the new address without the back-navigation dots.
96
+ let tmpRecurseAddress = pAddress.slice(tmpBackNavigationCount);
97
+ if (tmpParentAddressLength > 0)
98
+ {
99
+ tmpRecurseAddress = `${tmpParentAddressParts.slice(0, tmpParentAddressLength).join('.')}.${tmpRecurseAddress}`;
100
+ }
101
+ this.logInfo(`Back-navigation detected. Recursing back to address [${tmpRecurseAddress}]`);
102
+ return this.getValueAtAddress(tmpRootObject, tmpRecurseAddress);
103
+ }
104
+ }
105
+
61
106
  // This is the terminal address string (no more dots so the RECUSION ENDS IN HERE somehow)
62
107
  if (tmpSeparatorIndex == -1)
63
108
  {
@@ -245,14 +290,14 @@ class ManyfestObjectAddressResolverGetValue
245
290
  // Continue to manage the parent address for recursion
246
291
  tmpParentAddress = `${tmpParentAddress}${(tmpParentAddress.length > 0) ? '.' : ''}${tmpSubObjectName}`;
247
292
  // Recurse directly into the subobject
248
- return this.getValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference], tmpNewAddress, tmpParentAddress);
293
+ return this.getValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyReference], tmpNewAddress, tmpParentAddress, tmpRootObject);
249
294
  }
250
295
  else
251
296
  {
252
297
  // Continue to manage the parent address for recursion
253
298
  tmpParentAddress = `${tmpParentAddress}${(tmpParentAddress.length > 0) ? '.' : ''}${tmpSubObjectName}`;
254
299
  // We parsed a valid number out of the boxed property name, so recurse into the array
255
- return this.getValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber], tmpNewAddress, tmpParentAddress);
300
+ return this.getValueAtAddress(pObject[tmpBoxedPropertyName][tmpBoxedPropertyNumber], tmpNewAddress, tmpParentAddress, tmpRootObject);
256
301
  }
257
302
  }
258
303
  // The requirements to detect a boxed set element are:
@@ -280,7 +325,7 @@ class ManyfestObjectAddressResolverGetValue
280
325
  for (let i = 0; i < tmpArrayProperty.length; i++)
281
326
  {
282
327
  let tmpPropertyParentAddress = `${tmpParentAddress}[${i}]`;
283
- let tmpValue = this.getValueAtAddress(pObject[tmpBoxedPropertyName][i], tmpNewAddress, tmpPropertyParentAddress);
328
+ let tmpValue = this.getValueAtAddress(pObject[tmpBoxedPropertyName][i], tmpNewAddress, tmpPropertyParentAddress, tmpRootObject);
284
329
 
285
330
  tmpContainerObject[`${tmpPropertyParentAddress}.${tmpNewAddress}`] = tmpValue;
286
331
  }
@@ -311,7 +356,7 @@ class ManyfestObjectAddressResolverGetValue
311
356
  for (let i = 0; i < tmpObjectPropertyKeys.length; i++)
312
357
  {
313
358
  let tmpPropertyParentAddress = `${tmpParentAddress}.${tmpObjectPropertyKeys[i]}`;
314
- let tmpValue = this.getValueAtAddress(pObject[tmpObjectPropertyName][tmpObjectPropertyKeys[i]], tmpNewAddress, tmpPropertyParentAddress);
359
+ let tmpValue = this.getValueAtAddress(pObject[tmpObjectPropertyName][tmpObjectPropertyKeys[i]], tmpNewAddress, tmpPropertyParentAddress, tmpRootObject);
315
360
 
316
361
  // The filtering is complex but allows config-based metaprogramming directly from schema
317
362
  let tmpKeepRecord = this.checkFilters(pAddress, tmpValue);
@@ -335,7 +380,7 @@ class ManyfestObjectAddressResolverGetValue
335
380
  // If there is already a subobject pass that to the recursive thingy
336
381
  // Continue to manage the parent address for recursion
337
382
  tmpParentAddress = `${tmpParentAddress}${(tmpParentAddress.length > 0) ? '.' : ''}${tmpSubObjectName}`;
338
- return this.getValueAtAddress(pObject[tmpSubObjectName], tmpNewAddress, tmpParentAddress);
383
+ return this.getValueAtAddress(pObject[tmpSubObjectName], tmpNewAddress, tmpParentAddress, tmpRootObject);
339
384
  }
340
385
  else
341
386
  {
@@ -343,7 +388,7 @@ class ManyfestObjectAddressResolverGetValue
343
388
  // Continue to manage the parent address for recursion
344
389
  tmpParentAddress = `${tmpParentAddress}${(tmpParentAddress.length > 0) ? '.' : ''}${tmpSubObjectName}`;
345
390
  pObject[tmpSubObjectName] = {};
346
- return this.getValueAtAddress(pObject[tmpSubObjectName], tmpNewAddress, tmpParentAddress);
391
+ return this.getValueAtAddress(pObject[tmpSubObjectName], tmpNewAddress, tmpParentAddress, tmpRootObject);
347
392
  }
348
393
  }
349
394
  }
@@ -9,6 +9,8 @@
9
9
  //
10
10
  // The function does not need to alter the string -- just check the conditionals within.
11
11
 
12
+ // TODO: Consider making this an es6 class
13
+
12
14
  // Let's use indexOf since it is apparently the fastest.
13
15
  const _ConditionalStanzaStart = '<<~?';
14
16
  const _ConditionalStanzaStartLength = _ConditionalStanzaStart.length;
@@ -27,7 +27,7 @@ suite
27
27
  {
28
28
  test
29
29
  (
30
- 'Underlying template processors should be able to filter sets.',
30
+ 'Underlying template processor should be able to filter records and be fast.',
31
31
  (fTestComplete)=>
32
32
  {
33
33
  let _Manyfest = new libManyfest();
@@ -42,6 +42,10 @@ suite
42
42
 
43
43
  Expect(tmpTestResult).to.equal(true);
44
44
 
45
+ tmpTestRecord.Name = 'Bob';
46
+
47
+ Expect(templateParser(_Manyfest, tmpTestTemplate, tmpTestRecord)).to.equal(false);
48
+
45
49
  return fTestComplete();
46
50
  }
47
51
  )
@@ -12,6 +12,7 @@ var Expect = Chai.expect;
12
12
  let libManyfest = require('../source/Manyfest.js');
13
13
 
14
14
  let _SampleDataArchiveOrgFrankenberry = require('./Data-Archive-org-Frankenberry.json');
15
+ let _SampleDataYahooWeather = require('./Data-Yahoo-Weather.json');
15
16
 
16
17
  suite
17
18
  (
@@ -100,9 +101,36 @@ suite
100
101
  );
101
102
  suite
102
103
  (
103
- 'Advanced Read (with Arrays and Boxed Property addresses)',
104
+ 'Advanced Read (with Arrays and Boxed Property and Backwards navigation addresses)',
104
105
  ()=>
105
106
  {
107
+ test
108
+ (
109
+ 'Access relative objects',
110
+ (fTestComplete)=>
111
+ {
112
+ let _Manyfest = new libManyfest();
113
+ // Traverse a relative address
114
+ let tmpVideoPointer = _Manyfest.getValueAtAddress(_SampleDataArchiveOrgFrankenberry, 'files[0]');
115
+ Expect(tmpVideoPointer.original).to.equal('frankerberry_countchockula_1971.0001.mpg');
116
+ // The .. means go back one level
117
+ let tmpDir = _Manyfest.getValueAtAddress(_SampleDataArchiveOrgFrankenberry, 'files[0]..dir');
118
+ Expect(tmpDir).to.equal("/7/items/FrankenberryCountChoculaTevevisionCommercial1971");
119
+ fTestComplete();
120
+ }
121
+ );
122
+ test
123
+ (
124
+ 'Access relative objects complexly',
125
+ (fTestComplete)=>
126
+ {
127
+ let _Manyfest = new libManyfest();
128
+ Expect(_Manyfest.getValueAtAddress(_SampleDataYahooWeather, 'location.city')).to.equal('Sunnyvale');
129
+ // The .. means go back one level
130
+ Expect(_Manyfest.getValueAtAddress(_SampleDataYahooWeather, 'current_observation.wind...location.city')).to.equal('Sunnyvale');
131
+ fTestComplete();
132
+ }
133
+ );
106
134
  test
107
135
  (
108
136
  'Access specific array elements',