@function beforeList

load records for list view

@param {ImmutableCoreController} controller
@param {object} args
@param {array} fields
@param {string} title
@param {object} form
@param {object} defaultQueryArgs

@returns {Promise}
514002
function beforeList (controller, args, fields, title, form, links, defaultQueryArgs) {
    // get model from controller
    var model = controller.model
    // set limit
    var limit = args.limit || controller.defaultLimit
    var offset = args.offset || 0
    // set to true to show clear option for filters/sort
    var clear = false
    // set minimum limit to 2
    if (limit < 2) {
        limit = 2
    }
    // build arguments for query
    var query = {
        session: args.session,
    }
    // if query args are passed use them
    if (defined(defaultQueryArgs)) {
        _.merge(query, defaultQueryArgs)
    }
    // add order if set
    if (defined(args.orderColumn)) {
        query.order = [args.orderColumn]
        // if custom order is set add clear option
        clear = true
        // add direction if set
        if (defined(args.orderDirection)) {
            query.order.push(args.orderDirection)
        }
    }
    // add where if set
    if (defined(args.where)) {
        query.where = JSON.parse(args.where)
    }
    // included deleted records
    if (defined(args.deleted)) {
        // create where query if not set
        if (!defined(query.where)) {
            query.where = {}
        }
        // include deleted records - if argument is only then only deleted
        query.where.isDeleted = args.deleted === 'only'
            ? true: null
    }
    // add extra columns as query param options
    _.each(model.extraColumns, (spec, name) => {
        // if param is set in args add to where query
        if (typeof args[name] === 'string') {
            // create where query if not set
            if (!defined(query.where)) {
                query.where = {}
            }
            // if query is quoted then do exact match
            var queryArg = args[name].charAt(0) === '"' && args[name].charAt(args[name].length - 1) === '"'
                // strip leading and trailing quotes
                ? args[name].substr(1, args[name].length - 2)
                // add wildcards to string
                : `%${args[name]}%`
            // set like query
            query.where[name] = {like: queryArg}
            // if filter is set add clear option
            clear = true
            // and param to sort links
            _.each(fields, field => {
                if (field.orderAscUrl) {
                    field.orderAscUrl += '&'+name+'='+args[name]
                }
                if (field.orderDescUrl) {
                    field.orderDescUrl += '&'+name+'='+args[name]
                }
            })
        }
    })
    // if originalId set add to query
    if (args.originalId) {
        // create where query if not set
        if (!query.where) {
            query.where = {}
        }
        // set originalId in query
        query.where.originalId = {eq: args.originalId}
    }
    // do database query
    return model.query(query)
    // prepare args for primary method
    .then(result => {
        // remove session from query args for presentation
        delete query.session
        // fetch records
        return result.fetch(limit, offset)
        // resolve with result and record data
        .then(records => {
            // add actions to records
            _.each(records, record => {
                buildActions(controller, record)
            })
            // return data that will be merged into args for primary method
            return {
                clear: clear,
                fields: fields,
                form: form,
                links: links,
                query: query,
                records: records,
                result: {
                    length: result.length,
                },
                title: title,
            }
        })
    })
}
1002103
function queryParamsState(queryParamsArray, controller) {
  return queryParamsArray.reduce(
    (state, qp) => {
      let value = qp.value(controller);

      state[qp.key] = {
        value,
        serializedValue: qp.serializedValue(controller),
        as: qp.as,
        defaultValue: qp.defaultValue,
        changed: JSON.stringify(value) !== JSON.stringify(qp.defaultValue)
      };
      return state;
    },
    {},
    undefined
  );
}
14583
function initModelUnlink (args) {
    var controller = this
    var model = this.model
    // if model does not have id column then cannot use default controller
    if (!defined(model.columnName('id'))) {
        return
    }
    // set true if model has ny relations that link via another model
    var hasVia = false
    // check for relations
    _.each(model.relations, relation => {
        if (defined(relation.via)) {
            hasVia = true
        }
    })
    // if model does not have via then do not create link endpoing
    if (!hasVia) {
        return
    }
    // get accountId column
    var accountIdColumn = model.columnName('accountId') 
    // set role to authenticated if model requires account id
    var role = defined(args.defaultRole) 
        ? args.defaultRole
        : defined(accountIdColumn) && model.columns[accountIdColumn].null === false
            ? 'authenticated'
            : 'all'
    // index inputs
    var input = {
        // get current revision of record
        current: ['query.current', 'body.current'],
        // get record even if deleted
        deleted: ['query.deleted', 'body.deleted'],
        // ignore conflicts
        force: ['query.force', 'body.force'],
        // record id
        id: 'params.id',
        // url to redirect to when done
        redirect: ['query.redirect', 'body.redirect'],
        // http referrer
        referrer: 'headers.referer',
        // name of model to link to
        relation: ['query.relation', 'body.relation'],
        // id of model to link to
        relationId: ['query.relationId', 'body.relationId'],
    }
    // create path if it does not exist
    if (!this.paths['/:id/unlink']) {
        this.paths['/:id/unlink'] = {}
    }
    // add handler for POST /:id/link to link record to another
    this.paths['/:id/unlink'].post = this.paths['/:id/unlink'].get = [
        {
            before: function (args) {
                // load primary record and related record
                return loadRecordAndRelation(controller, args)
            },
            input: input,
            method: function (args) {
                // unlink related record from primary record
                return unlinkModel(controller, args)
            },
            methodName: 'unlink',
            role: role,
        },
    ]
}
705093
function initField (form, args) {
    // field specification to return
    var field = {}
    // get model
    var model = form.model
    // set default based on schema data
    if (form.model.schemaData) {
        // get data properites from schema
        var properties = form.model.schemaData.properties
        // create lookup table of required properties
        var required = _.zipObject(form.model.schemaData.required, _.map(form.model.schemaData.required, () => true))
    }
    else {
        var properties = {}
        var required = {}
    }
    // string is passed then use as property name
    if (typeof args === 'string') {
        field.property = args
        // set args as empty object so that it can be checked for values
        args = {}
    }
    else {
        // require field to be object
        assert.ok(args && typeof args === 'object', 'field must be object')
        // field can be a section divider
        if (args.legend) {
            return args
        }
        else {
            // require field to have property
            assert.ok(typeof args.property === 'string' && args.property.length, 'field must have property')
            // set property from args
            field.property = args.property
        }
    }
    // if property is required make field required
    if (required[field.property]) {
        field.required = true
    }
    // set path base on property name
    field.path = changeCase.paramCase(field.property)
    // get property schema for field
    var schema = properties[field.property]
    // build field data from args and schema
    return buildField(args, field, form, model, schema)
}
93934
function initAccessControl (args) {
    // get global access control instance
    var accessControl = ImmutableAccessControl.getGlobal()
    // check for deprecated access control
    if (defined(args.accessControl)) {
        throw new Error('model local accessControl is deprecated')
    }
    // check for deprecated access model if passed
    if (defined(args.accessModel)) {
        throw new Error('accessModel is deprecated')
    }
    // set access id column if passed
    if (args.accessIdName) {
        // set access id name
        this.accessIdName = args.accessIdName
        // get column spec
        var spec = this.columns[this.accessIdName]
        // column for access id name must exist
        this.assert(defined(spec), `column not defined for accessIdName ${args.accessIdName}`)
        // column must be id
        this.assert(spec.type === 'id', `accessIdName column ${args.accessIdName} must have type id`)
        // set access id name with access control provider
        accessControl.setAccessIdName(this.name, this.accessIdName)
    }
    // set default access id name o model
    else {
        // default is accountId if model has an account id
        this.accessIdName = this.defaultColumnsInverse.accountId ? 'accountId' : undefined
    }
    // if rules not passed skip adding
    if (!defined(args.accessControlRules)) {
        return
    }
    // require access control rules to be array
    this.assert(Array.isArray(args.accessControlRules), 'accessControlRules must be array')
    // add each access control rule
    _.each(args.accessControlRules, accessControlRule => {
        // if rule is a string then it is for `all` role
        if (typeof accessControlRule === 'string') {
            // prepend model:<modelName>: to rule
            accessControlRule = `model:${this.name}:${accessControlRule}`
            // add rule with all role
            accessControl.setRule(['all', accessControlRule], true)
        }
        // otherwise must be array with role(s) and rule as last element
        else if (Array.isArray(accessControlRule)) {
            // get index of last element
            var lastIdx = accessControlRule.length - 1
            // prepend model:<modelName>: to rule
            accessControlRule[lastIdx] = `model:${this.name}:${accessControlRule[lastIdx]}`
            // add rule
            accessControl.setRule(accessControlRule, true)
        }
        // error
        else {
            throw this.error('string or array required for accessControlRules element')
        }
    })
}
819012
function loadListByName(listName, args, skipCache = false) {
    checkIsString('listName', listName);
    const configurationElement = getElement(listName);
    if (typeof configurationElement !== 'function') {
        throw new Error(`You are trying to load the reference list: ${listName} which does not have a list configure.`);
    }
    let now = _getTimeStamp();
    if (cache[listName] && (now - cache[listName].timeStamp) < getCacheDuration() && !skipCache) {
        _deletePromiseWaiting(listName);
        //console.info('data served from cache', listName, cache[listName].value);
        return Promise.resolve(cache[listName].value);
    }
    //Call the service, the service must return a promise.
    return configurationElement(args)
        .then((data) => {
            return _cacheData(listName, data)
        });
}
975972
function (req, res, next) {
            if (!req.miajs.controllerDebugInfo) {
                req.miajs.controllerDebugInfo = {};
            }
            if (controller.name && controller.version) {
                req.miajs.controllerDebugInfo[controller.name + '_' + controller.version] = {'runtime': Date.now() - req.miajs.controllerStart};
            }
            next();
        }
304009
function (req, res) {
    var options = {
      operation: 'LIST',
      res: res,
    };
    exports.list.before(req, res, options);
    vulpejs.models.list({
      model: req.params.model,
      query: req.params.query || {},
      populate: req.params.populate || '',
      sort: req.params.sort || {},
      userId: req.session['user-id'],
      callback: {
        success: function (items) {
          exports.list.after(req, res, items);
          res.json({
            items: items,
          });
        },
        error: function (error) {
          exports.response.error(options, error);
        },
      },
    });
  }
269972
public static void initDefaultParameterValues(QueryParameter param,
                                                  List<Serializable> defValues, Map<String, Object> parameterValues) throws QueryException {

        if (param.getSelection().equals(QueryParameter.SINGLE_SELECTION)) {
            parameterValues.put(param.getName(), defValues.get(0));
        } else {
            Object[] val = new Object[defValues.size()];
            for (int k = 0, size = defValues.size(); k < size; k++) {
                val[k] = defValues.get(k);
            }
            parameterValues.put(param.getName(), val);
        }
    }
490121
public function beforeFetch(&$args) {
        $model = &$args[0];
        $select = &$args[1];

        $isCms = $model->isCmsContext();
        if (!$isCms && !$this->_forceI18nOutput) {
            return;
        }
        $this->_modifySearchQuery($select, $model);
        $this->bindWithI18nModel($model);
    }
149120
function init() {
		config = app.config;

		defaultController = config.defaultControllerFactory(app.models);

		// load controllers
		var controllerDir = path.join(config.rootDir, config.paths.controllers);
		var controllerFiles = fs.readdirSync(controllerDir);
		controllerFiles.forEach(function(controllerFile) {
			var controllerName = controllerFile.substring(0, controllerFile.indexOf('Controller'));
			var controllerDef = require(path.join(controllerDir, controllerFile));
			var controller;
			if (controllerDef.noDefaultActions) {
				controller = controllerDef;
			} else {
				controller = Object.create(defaultController);
				controller = Object.merge(controller, controllerDef);
			}
			app.controllers[controllerName] = controller;
		});

		applyPathPolicies();

		var routes = config.routes,
			parsed = [];

		parseResourceRoutes();

		for (var route in routes) {
			parsed.push(parseRoute(route, routes[route]));
		}

		parsed.forEach(function(route) {
			if(!route.target)
				return;

			if (Object.isString(route.target)) {
				if (route.verbs[0] !== 'static' && route.target.charAt(0) === '/') {
					route.target = {redirect: route.target};
				} else {
					var parts = route.target.split('.');
					if (parts.length === 2) {
						route.target = {controller: parts[0], action: parts[1]};
					}
				}
			}
			if (!Object.isObject(route.target)) {
				route.target = {controller: route.target};
			}

			route.verbs.forEach(function (verb) {
				if (verb === 'resource') {
					addResourceRoute(route.path, route.target.controller);
				} else if (verb === 'static') {
					addStaticRoute(route.path, route.target.controller);
				} else if (route.target.redirect) {
					addRedirectRoute(verb, route.path, route.target.redirect);
				} else {
					addSingleRoute(verb, route.path, route.target.controller, route.target.action);
				}
			});
		});

		if(config.autoRoute) {
			resourceRouting.forEach(function(route) {
				var actionPath = path.join('/', config.autoRoutePath, route.path);
				route.verbs.forEach(function (verb) {
					app[verb](actionPath, function(req, res, next) {
						var controllerName = req.params.controller.singularize();
						var actionName = route.target.action;
						req.controller = controllerName;
						req.action = actionName;

						var action = getAction(controllerName, actionName);
						if (action) {
							var policies = getPolicies(controllerName, actionName);
							if (policies.length > 0) {
								var policyIdx = 0;
								var nextPolicy = function() {
									policyIdx++;
									if (policyIdx < policies.length) {
										policies[policyIdx](req, res, nextPolicy);
									} else {
										action(req, res, next);
									}
								};
								policies[0](req, res, nextPolicy);
							} else {
								action(req, res, next);
							}
						} else {
							next();
						}
					});
				});
			});
		}
	}
291436
function buildForms (args, controller, forms, instance) {
    // promises to be resolved once all forms built
    var promises = []
    // build forms from controller spec
    _.each(forms, form => {
        if (form.type === 'link') {
            var promise = buildFormLink(args, controller, form, instance)
        }
        // add promise to list
        promises.push(promise)
    })
    // wait for promises to resolve then resolve with forms
    return Promise.all(promises)
}
687926
function setFormFields () {
  var query = qs.parse(window.location.search.substr(1));

  setCheckbox(form.allow.json, query["allow-json"]);
  setCheckbox(form.allow.yaml, query["allow-yaml"]);
  setCheckbox(form.allow.text, query["allow-text"]);
  setCheckbox(form.allow.empty, query["allow-empty"]);
  setCheckbox(form.allow.unknown, query["allow-unknown"]);
  setCheckbox(form.refs.external, query["refs-external"]);
  setCheckbox(form.refs.circular, query["refs-circular"]);
  setCheckbox(form.validate.schema, query["validate-schema"]);
  setCheckbox(form.validate.spec, query["validate-spec"]);

  // If a custom URL is specified, then show the "Your API" tab
  if (query.url) {
    form.url.val(query.url);
  }

  // If a method is specified, then change the "Validate!" button
  if (query.method) {
    query.method = query.method.toLowerCase();
    if (["parse", "resolve", "bundle", "dereference", "validate"].indexOf(query.method) !== -1) {
      form.method.button.val(query.method);
    }
  }
}
1180863
function paginate(q, options, callback) {
  /*jshint validthis:true */
  var query, skipFrom, sort, columns, populate, lean, model = this;
  columns = options.columns || null;
  sort = options.sort || options.sortBy || null; // TODO: get rid of sortBy in major version
  populate = options.populate || null;
  var lean = options.lean || false;
  var pageNumber = options.page || 1;
  var resultsPerPage = options.limit || 10;
  skipFrom = (pageNumber * resultsPerPage) - resultsPerPage;
  query = model.find(q);
  if (columns !== null) {
    query = query.select(options.columns);
  }
  query = query.skip(skipFrom).limit(resultsPerPage);
  if (sort !== null) {
    query.sort(sort);
  }
  if (populate) {
    if (Array.isArray(populate)) {
      populate.forEach(function(field) {
        query = query.populate(field);
      });
    } else {
      query = query.populate(populate);
    }
  }
  if (lean) {
    query.lean();
  }

  if (typeof callback === 'function') {
    return handleCallback(query, q, model, resultsPerPage, callback);
  } else {
    return handlePromise(query, q, model, resultsPerPage);
  }
}
51567
function (cb) {

                let fields = Object.keys(req.linz.model.list.fields);

                // Work in the title field
                linz.api.model.titleField(req.params.model, 'title', (err, titleField) => {

                    if (err) {
                        return cb(err);
                    }

                    fields.push(titleField);

                    const select = fields.join(' ');

                    query.select(select);

                    // If they've provided the `listQuery` static, use it to allow customisation of the fields we'll retrieve.
                    if (!req.linz.model.listQuery) {
                        return cb();
                    }

                    req.linz.model.listQuery(req, query, cb);

                });

            }
381999
function updateQueryForNextPage(pulledRecords) {
        return Platform.async(function(callback) {
            callback();
        })().then(function() {

            if (!pulledRecords) {
                throw new Error('Something is wrong. pulledRecords cannot be null at this point');
            }

            var lastRecord = pulledRecords[ pulledRecords.length - 1];

            if (!lastRecord) {
                throw new Error('Something is wrong. Possibly invalid response from the server. lastRecord cannot be null!');
            }

            var lastRecordTime = lastRecord[tableConstants.sysProps.updatedAtColumnName];

            if (!_.isDate(lastRecordTime)) {
                throw new Error('Property ' + tableConstants.sysProps.updatedAtColumnName + ' of the last record should be a valid date');
            }

            if (lastRecordTime.getTime() === lastKnownUpdatedAt.getTime()) {
                pagePullQuery.skip(pagePullQuery.getComponents().skip + pulledRecords.length);
            } else {
                buildQueryFromLastKnownUpdateAt(lastRecordTime);
            }
        });
    }
528102
function (list, location, ext, sequence, perms, title, src) {
			var actions = list.get_userCustomActions();

			var action = actions.add();

			action.set_title(title);
			action.set_location(location);
			action.set_commandUIExtension(ext);
			action.set_sequence(sequence || 0);
			(src && action.set_scriptSrc(src));
			if (perms)
				action.set_rights(perms);
			action.update();
			ctx.load(action);
			var dfd = $.Deferred();

			ctx.executeQueryAsync(function () {
				trace.log("addCustomAction.done");
				dfd.resolve(action);
			}, function (r, a) { ns.sp.reqFailure(r, a, "addCustomAction", dfd); });

			return dfd.promise();
		}