server/models/zl-site-content-set.js
function makeEntity(req, res, all, top, data, path = '', promises) {
  var Role = app.models.Role;
  const { zlSite } = res.locals;
  const zsBaseUrlPath = (zlSite.zsBaseUrlPath) ? `/${zlSite.zsBaseUrlPath}/` : '/'

  _.forEach(_.filter(all, ['scsParent', top]), function(val) {
    val = val.toJSON();

    /* check if have children
     NOTE: since children loads first, they will return even if parent
     permission is denied, so must assign children correct permission/role */
    if (_.find(all, ['scsParent', val.scsId])) {
      data = makeEntity(req, res, all, val.scsId, data, path+val.scsSlug+'/', promises);
    }

    let loadThisEntity = () => {
      data[val.scsId] = val;
      // placeholder for content id list
      data[val.scsId]['contents'] = [];
      // set page path
      data[val.scsId]['path'] = `${path}${val.scsSlug}`;
      data[val.scsId]['realPath'] = `${zsBaseUrlPath}${data[val.scsId]['path']}`;
    }

    // make sure they have correct permission
    // verify that they have permission to this page
    let ctx = app.locals.authCtx(req, res);
    return promises.push( new Promise((resolve, reject) => {
      Role.isInRole(val.scsPermission, ctx, (err, isInRole) => {
        if (isInRole) {
          loadThisEntity();
        }
        resolve();
      });
    }));

    // if we reach here, I guess we can load page
    loadThisEntity();
  });

  return data;
}
function makeEntity(req, res, all, top, data, path = '', promises) {
  var Role = app.models.Role;
  const { zlSite } = res.locals;
  const zsBaseUrlPath = (zlSite.zsBaseUrlPath) ? `/${zlSite.zsBaseUrlPath}/` : '/'

  _.forEach(_.filter(all, ['scsParent', top]), function(val) {
    val = val.toJSON();

    /* check if have children
     NOTE: since children loads first, they will return even if parent
     permission is denied, so must assign children correct permission/role */
    if (_.find(all, ['scsParent', val.scsId])) {
      data = makeEntity(req, res, all, val.scsId, data, path+val.scsSlug+'/', promises);
    }

    let loadThisEntity = () => {
      data[val.scsId] = val;
      // placeholder for content id list
      data[val.scsId]['contents'] = [];
      // set page path
      data[val.scsId]['path'] = `${path}${val.scsSlug}`;
      data[val.scsId]['realPath'] = `${zsBaseUrlPath}${data[val.scsId]['path']}`;
    }

    // make sure they have correct permission
    // verify that they have permission to this page
    let ctx = app.locals.authCtx(req, res);
    return promises.push( new Promise((resolve, reject) => {
      Role.isInRole(val.scsPermission, ctx, (err, isInRole) => {
        if (isInRole) {
          loadThisEntity();
        }
        resolve();
      });
    }));

    // if we reach here, I guess we can load page
    loadThisEntity();
  });

  return data;
}
makes list of pages for main or subsite