@@ -9,6 +9,7 @@ const exception = require('./exception');
99const NEWLINE = require ( 'os' ) . EOL ;
1010const ANY_NEWLINE = / \r \n | \r | \n / g;
1111const url = require ( 'url' ) ;
12+ const hClasses = require ( '../lufile/classes/hclasses' ) ;
1213const helpers = {
1314
1415 /**
@@ -163,36 +164,213 @@ const helpers = {
163164 if ( ! finalLUISJSON ) {
164165 return
165166 }
166- let v5DefFound = false ;
167- v5DefFound = ( finalLUISJSON . entities || [ ] ) . find ( i => i . children || i . features ) ||
168- ( finalLUISJSON . intents || [ ] ) . find ( i => i . features ) ||
169- ( finalLUISJSON . composites || [ ] ) . find ( i => i . features ) ||
170- ( finalLUISJSON . luis_schema_version === '6.0.0' ) ;
171- if ( v5DefFound ) {
172- finalLUISJSON . luis_schema_version = "6.0.0" ;
173- if ( finalLUISJSON . hasOwnProperty ( "model_features" ) ) {
174- if ( finalLUISJSON . model_features !== undefined ) {
175- finalLUISJSON . phraselists = finalLUISJSON . phraselists || [ ] ;
176- finalLUISJSON . model_features . forEach ( item => {
177- if ( item . enabledForAllModels === undefined ) item . enabledForAllModels = true
178- finalLUISJSON . phraselists . push ( Object . assign ( { } , item ) )
179- } ) ;
180- }
181- delete finalLUISJSON . model_features ;
182- }
183- ( finalLUISJSON . composites || [ ] ) . forEach ( composite => {
184- let children = composite . children ;
185- composite . children = [ ] ;
186- children . forEach ( c => {
187- if ( c . name === undefined ) {
188- composite . children . push ( { name : c } )
189- } else {
190- composite . children . push ( c )
191- }
167+ updateToV7 ( finalLUISJSON ) ;
168+ }
169+ } ;
170+
171+ module . exports = helpers ;
172+
173+ const updateToV7 = function ( finalLUISJSON ) {
174+ let v7DefFound = false ;
175+ v7DefFound = ( finalLUISJSON . entities || [ ] ) . find ( i => i . children || i . features ) ||
176+ ( finalLUISJSON . intents || [ ] ) . find ( i => i . features ) ||
177+ ( finalLUISJSON . composites || [ ] ) . find ( i => i . features ) ||
178+ ( finalLUISJSON . luis_schema_version === '6.0.0' ||
179+ ( finalLUISJSON . luis_schema_version === '7.0.0' ) ) ;
180+ if ( v7DefFound ) {
181+ finalLUISJSON . luis_schema_version = "7.0.0" ;
182+ if ( finalLUISJSON . hasOwnProperty ( "model_features" ) ) {
183+ if ( finalLUISJSON . model_features !== undefined ) {
184+ finalLUISJSON . phraselists = finalLUISJSON . phraselists || [ ] ;
185+ finalLUISJSON . model_features . forEach ( item => {
186+ if ( item . enabledForAllModels === undefined )
187+ item . enabledForAllModels = true ;
188+ finalLUISJSON . phraselists . push ( Object . assign ( { } , item ) ) ;
192189 } ) ;
190+ }
191+ delete finalLUISJSON . model_features ;
192+ }
193+ ( finalLUISJSON . composites || [ ] ) . forEach ( composite => {
194+ let children = composite . children ;
195+ composite . children = [ ] ;
196+ children . forEach ( c => {
197+ if ( c . name === undefined ) {
198+ composite . children . push ( { name : c } ) ;
199+ }
200+ else {
201+ composite . children . push ( c ) ;
202+ }
203+ } ) ;
204+ } ) ;
205+ ( finalLUISJSON . entities || [ ] ) . forEach ( entity => transformAllEntityConstraintsToFeatures ( entity ) ) ;
206+ ( finalLUISJSON . intents || [ ] ) . forEach ( intent => addIsRequiredProperty ( intent ) ) ;
207+ transformUtterancesWithNDepthEntities ( finalLUISJSON )
208+ }
209+ }
210+
211+ const constructEntityParentTree = function ( entityCollection , entityParentTree , curPath )
212+ {
213+ entityCollection . forEach ( entity => {
214+ if ( entity . children !== undefined && Array . isArray ( entity . children ) && entity . children . length !== 0 ) {
215+ constructEntityParentTree ( entity . children , entityParentTree , curPath . concat ( entity . name ) ) ;
216+ }
217+ updateTreeWithNode ( curPath , entity . name , entityParentTree )
218+ } )
219+ }
220+ const updateTreeWithNode = function ( curPath , entityName , entityParentTree ) {
221+ let revPath = JSON . parse ( JSON . stringify ( curPath . reverse ( ) ) ) ;
222+ if ( entityParentTree [ entityName ] === undefined ) {
223+ entityParentTree [ entityName ] = [ revPath ] ;
224+ }
225+ else {
226+ if ( entityParentTree [ entityName ] . find ( item => item . join ( '->' ) == revPath . join ( '->' ) ) === undefined )
227+ entityParentTree [ entityName ] . push ( revPath ) ;
228+ }
229+ curPath . reverse ( ) ;
230+ }
231+
232+ const transformUtterancesWithNDepthEntities = function ( finalLUISJSON ) {
233+ let entityParentTree = { } ;
234+ const curPath = [ "$root$" ] ;
235+ constructEntityParentTree ( finalLUISJSON . entities , entityParentTree , curPath ) ;
236+ finalLUISJSON . utterances . forEach ( utt => {
237+ if ( utt . entities !== undefined && Array . isArray ( utt . entities ) && utt . entities . length !== 0 ) {
238+ // sort all entities by start and end position
239+ utt . entities = objectSortByStartPos ( utt . entities )
240+ let entityIdsToRemove = [ ] ;
241+ utt . entities . forEach ( ( item , idx ) => {
242+ // find the immediate parents of this entity
243+ // if the enity has a role, find by that
244+ let entityToFind = item . role || item . entity ;
245+ if ( isRootEntity ( entityToFind , finalLUISJSON . entities ) ) return ;
246+
247+ if ( entityParentTree [ entityToFind ] === undefined ) {
248+ return ;
249+ }
250+ let parentPathsForEntity = entityParentTree [ entityToFind ] ;
251+ let parentIdx = [ ] ;
252+ parentPathsForEntity . forEach ( path => {
253+ utt . entities . find ( ( i , id ) => {
254+ if ( i . entity === path [ 0 ] && i . startPos <= item . startPos && i . endPos >= item . endPos ) {
255+ parentIdx . push ( id ) ;
256+ }
257+ } )
258+ } )
259+ if ( parentIdx . length !== 0 ) {
260+ parentIdx . forEach ( id => {
261+ if ( item . role !== undefined ) {
262+ item . entity = item . role ;
263+ delete item . role ;
264+ }
265+ if ( utt . entities [ id ] . children === undefined ) {
266+ utt . entities [ id ] . children = [ item ]
267+ } else {
268+ utt . entities [ id ] . children . push ( item ) ;
269+ }
270+ } )
271+ entityIdsToRemove . push ( idx ) ;
272+ }
193273 } )
274+ if ( entityIdsToRemove . length !== 0 ) {
275+ entityIdsToRemove . sort ( ( a , b ) => b - a ) . forEach ( id => {
276+ utt . entities . splice ( id , 1 ) ;
277+ } )
278+ }
279+ // remove any children that are not a root entity
280+ removeNonRootChildren ( utt . entities , finalLUISJSON . entities )
194281 }
282+ } )
283+ }
284+
285+ const removeNonRootChildren = function ( entitiesList , allEntitiesList ) {
286+ let idxToRemove = [ ] ;
287+ entitiesList . forEach ( ( entity , idx ) => {
288+ if ( ! isRootEntity ( entity . entity , allEntitiesList ) ) {
289+ idxToRemove . push ( idx )
290+ }
291+ } )
292+ if ( idxToRemove . length !== 0 ) {
293+ idxToRemove . sort ( ( a , b ) => b - a ) . forEach ( id => entitiesList . splice ( id , 1 ) ) ;
294+ idxToRemove = [ ] ;
195295 }
296+ // de-dupe children
297+ deDupeChildren ( entitiesList ) ;
196298}
197299
198- module . exports = helpers ;
300+ const deDupeChildren = function ( collection ) {
301+ collection . forEach ( entity => {
302+ if ( entity . children !== undefined && Array . isArray ( entity . children ) && entity . children . length !== 0 ) {
303+ let childAsStr = entity . children . map ( item => JSON . stringify ( item ) ) ;
304+ var newList = [ ] ;
305+ childAsStr . forEach ( item => {
306+ if ( newList . indexOf ( item ) === - 1 ) newList . push ( item )
307+ } )
308+ entity . children = newList . map ( item => JSON . parse ( item ) )
309+ deDupeChildren ( entity . children )
310+ }
311+ } )
312+ }
313+
314+ const isRootEntity = function ( entityName , entitiesCollection ) {
315+ if ( ( entitiesCollection || [ ] ) . find ( ecEntity => ecEntity . name == entityName ) !== undefined )
316+ return true
317+ return false
318+ }
319+
320+ const findParent = function ( entityInUtt , entityCollection , parentTree , curParent ) {
321+ let numOfParentsFound = 0 ;
322+ entityCollection . forEach ( childEntity => {
323+ if ( childEntity . name == entityInUtt . entity ) {
324+ parentTree [ curParent ] = childEntity . name ;
325+ numOfParentsFound ++ ;
326+ }
327+ if ( childEntity . children !== undefined && Array . isArray ( childEntity . children ) && childEntity . children . length !== 0 ) {
328+ parentTree [ childEntity . name ] = { } ;
329+ numOfParentsFound += findParent ( entityInUtt , childEntity . children , parentTree [ childEntity . name ] , childEntity . name )
330+ }
331+ } ) ;
332+ return numOfParentsFound ;
333+ }
334+
335+ const objectSortByStartPos = function ( objectArray ) {
336+ let ObjectByStartPos = objectArray . slice ( 0 ) ;
337+ ObjectByStartPos . sort ( function ( a , b ) {
338+ if ( a . startPos === b . startPos )
339+ return a . endPos - b . endPos ;
340+ return a . startPos - b . startPos ;
341+ } )
342+ return ObjectByStartPos
343+ }
344+
345+ const transformAllEntityConstraintsToFeatures = function ( entity ) {
346+ addIsRequiredProperty ( entity ) ;
347+ if ( entity . hasOwnProperty ( "instanceOf" ) && entity . instanceOf !== null ) {
348+ if ( entity . hasOwnProperty ( "features" ) && Array . isArray ( entity . features ) ) {
349+ let featureFound = ( entity . features || [ ] ) . find ( i => i . modelName == entity . instanceOf ) ;
350+ if ( featureFound !== undefined ) {
351+ if ( featureFound . featureType === undefined )
352+ featureFound . isRequired = true ;
353+ }
354+ else {
355+ entity . features . push ( new hClasses . entityFeature ( entity . instanceOf , true ) ) ;
356+ }
357+ }
358+ else {
359+ if ( entity . instanceOf !== "" && entity . instanceOf !== null )
360+ entity . features = [ new hClasses . entityFeature ( entity . instanceOf , true ) ] ;
361+ }
362+ }
363+ delete entity . instanceOf ;
364+ if ( ! entity . children || entity . children . length === 0 )
365+ return ;
366+ entity . children . forEach ( c => transformAllEntityConstraintsToFeatures ( c ) ) ;
367+ } ;
368+
369+ const addIsRequiredProperty = function ( item ) {
370+ ( item . features || [ ] ) . forEach ( feature => {
371+ if ( feature . isRequired === undefined )
372+ feature . isRequired = false ;
373+ delete feature . featureType ;
374+ delete feature . modelType ;
375+ } ) ;
376+ }
0 commit comments