/*  *******************************************************************************************
 *  ATTENTION!
 *  THIS IS A GENERATED FILE FROM https://github.com/salesforce/lds
 *  If you would like to contribute to LDS, please follow the steps outlined in the git repo.
 *  Any changes made to this file in p4 will be automatically overwritten.
 *  *******************************************************************************************
 */
const { assign, create, freeze, keys } = Object;

function isFieldId(value) {
    return (value && typeof value.objectApiName === 'string' && typeof value.fieldApiName === 'string');
}
/**
 * Split the object API name and field API name from a qualified field name.
 * Eg: Opportunity.Title returns ['Opportunity', 'Title']
 * Eg: Opportunity.Account.Name returns ['Opportunity', 'Account.Name']
 * @param fieldApiName The qualified field name.
 * @return The object and field API names.
 */
function splitQualifiedFieldApiName(fieldApiName) {
    const idx = fieldApiName.indexOf('.');
    if (idx < 1) {
        // object api name must non-empty
        throw new TypeError('Value does not include an object API name.');
    }
    return [fieldApiName.substring(0, idx), fieldApiName.substring(idx + 1)];
}

function isString(value) {
    return typeof value === 'string';
}

/**
 * Returns the field API name, qualified with an object name if possible.
 * @param value The value from which to get the qualified field API name.
 * @return The qualified field API name.
 */
function getFieldApiName(value) {
    // Note: tightening validation logic changes behavior from userland getting
    // a server-provided error to the adapter noop'ing. In 224 we decided to not
    // change the behavior.
    if (isString(value)) {
        const trimmed = value.trim();
        if (trimmed.length > 0) {
            return trimmed;
        }
    }
    else if (isFieldId(value)) {
        return value.objectApiName + '.' + value.fieldApiName;
    }
    return undefined;
}
/**
 * Returns a new object that has a list of fields that has been filtered by
 * edited fields. Only contains fields that have been edited from their original
 * values (excluding Id which is always copied over).
 * @param input The RecordInputRepresentation object to filter.
 * @param original The Record object that contains the original field values.
 * @returns RecordInputRepresentation, see the description
 */
function createRecordInputFilteredByEditedFields(input, original) {
    const filteredRecordInput = getRecordInput();
    // Always copy over any existing id.
    if (original.id) {
        filteredRecordInput.fields.Id = original.id;
    }
    const recordInputFields = input.fields;
    const originalRecordFields = original.fields;
    const recordInputFieldPropertyNames = keys(recordInputFields);
    for (let i = 0, len = recordInputFieldPropertyNames.length; i < len; i++) {
        const fieldName = recordInputFieldPropertyNames[i];
        let originalRecordFieldsEntry;
        if (originalRecordFields) {
            originalRecordFieldsEntry = originalRecordFields[fieldName];
        }
        if (!originalRecordFieldsEntry ||
            (originalRecordFields &&
                recordInputFields[fieldName] !== originalRecordFieldsEntry.value)) {
            filteredRecordInput.fields[fieldName] = recordInputFields[fieldName];
        }
    }
    return filteredRecordInput;
}
/**
 * Returns an object with its data populated from the given record. All fields
 * with values that aren't nested records will be assigned. This object can be
 * used to create a record.
 * @param record The record that contains the source data.
 * @param objectInfo The ObjectInfo corresponding to the apiName on the record.
 *        If provided, only fields that are createable=true (excluding Id) will
 *        be assigned to the object return value.
 * @returns RecordInputRepresentation See description.
 */
function generateRecordInputForCreate(record, objectInfo) {
    const recordInput = _generateRecordInput(record, field => field.createable === true, objectInfo);
    recordInput.apiName = record.apiName;
    // fields.Id is not required for CREATE which might have been copied over,
    // so delete fields.Id
    delete recordInput.fields.Id;
    return recordInput;
}
/**
 * Returns an object with its data populated from the given record. All fields
 * with values that aren't nested records will be assigned. This object can be
 * used to update a record.
 * @param record The record that contains the source data.
 * @param objectInfo The ObjectInfo corresponding to the apiName on the record.
 *        If provided, only fields that are updateable=true (excluding Id) will
 *        be assigned to the object return value.
 * @returns RecordInputRepresentation See description.
 */
function generateRecordInputForUpdate(record, objectInfo) {
    const recordInput = _generateRecordInput(record, field => field.updateable === true, objectInfo);
    if (!record.id) {
        throw new Error('record must have id for update');
    }
    // Always copy over any existing id.
    recordInput.fields.Id = record.id;
    return recordInput;
}
function isRecordInputFieldValue(unknown) {
    const type = typeof unknown;
    return unknown === null || type === 'string' || type === 'number' || type === 'boolean';
}
/**
 * Returns an object with its data populated from the given record. All fields
 * with values that aren't nested records will be assigned.
 * @param record The record that contains the source data.
 * @param copyFieldPredicate predicate to determine if a field should be copied.
 *        Required if "objectInfo" parameter is passed.
 * @param objectInfo The ObjectInfo corresponding to the apiName on the record.
 *        If provided, only fields that match the copyFieldPredicate (excluding
 *        Id) will be assigned to the object return value.
 * @returns RecordInputRepresentation
 */
function _generateRecordInput(record, copyFieldPredicate, objectInfo) {
    const recordInput = getRecordInput();
    const recordFields = record.fields;
    let objectInfoFields;
    if (objectInfo) {
        objectInfoFields = objectInfo.fields;
    }
    const recordFieldPropertyNames = keys(recordFields);
    for (let i = 0, len = recordFieldPropertyNames.length; i < len; i++) {
        const fieldName = recordFieldPropertyNames[i];
        const recordFieldsFieldNameEntry = recordFields[fieldName].value;
        if (isRecordInputFieldValue(recordFieldsFieldNameEntry)) {
            if (objectInfoFields && copyFieldPredicate) {
                const objectInfoFieldsFieldNameValue = objectInfoFields[fieldName];
                if (objectInfoFieldsFieldNameValue &&
                    copyFieldPredicate(objectInfoFieldsFieldNameValue)) {
                    recordInput.fields[fieldName] = recordFieldsFieldNameEntry;
                }
            }
            else {
                recordInput.fields[fieldName] = recordFieldsFieldNameEntry;
            }
        }
    }
    return recordInput;
}
/**
 * Gets a new Record Input.
 */
function getRecordInput() {
    return {
        apiName: undefined,
        fields: {},
    };
}
/**
 * Gets a field's value from a record.
 * @param record The record.
 * @param field The qualified API name of the field to return.
 * @returns The field's value (which may be a record in the case of spanning
 *          fields), or undefined if the field isn't found.
 */
function getFieldValue(record, field) {
    const fieldValueRepresentation = getField(record, field);
    if (fieldValueRepresentation === undefined) {
        return undefined;
    }
    if (isFieldValueRepresentation(fieldValueRepresentation)) {
        return fieldValueRepresentation.value;
    }
    return fieldValueRepresentation;
}
/**
 * Gets a field's display value from a record.
 * @param record The record.
 * @param field The qualified API name of the field to return.
 * @returns The field's display value, or undefined if the field isn't found.
 */
function getFieldDisplayValue(record, field) {
    const fieldValueRepresentation = getField(record, field);
    if (fieldValueRepresentation === undefined) {
        return undefined;
    }
    if (isFieldValueRepresentation(fieldValueRepresentation)) {
        return fieldValueRepresentation.displayValue;
    }
    return fieldValueRepresentation;
}
function isFieldValueRepresentation(unknown) {
    if (typeof unknown !== 'object' || unknown === null) {
        return false;
    }
    return 'value' in unknown && 'displayValue' in unknown;
}
function getField(record, field) {
    const fieldApiName = getFieldApiName(field);
    if (fieldApiName === undefined) {
        return undefined;
    }
    const unqualifiedField = splitQualifiedFieldApiName(fieldApiName)[1];
    const fields = unqualifiedField.split('.');
    let r = record;
    while (r && r.fields) {
        const f = fields.shift();
        const fvr = r.fields[f];
        if (fvr === undefined) {
            return undefined;
        }
        else if (fields.length > 0) {
            r = fvr.value;
        }
        else {
            return fvr;
        }
    }
    return r;
}

var LayoutType;
(function (LayoutType) {
    LayoutType["Full"] = "Full";
    LayoutType["Compact"] = "Compact";
})(LayoutType || (LayoutType = {}));

var LayoutMode;
(function (LayoutMode) {
    LayoutMode["View"] = "View";
    LayoutMode["Edit"] = "Edit";
    LayoutMode["Create"] = "Create";
})(LayoutMode || (LayoutMode = {}));
const getListUiByApiName_ConfigPropertyNames = {
    displayName: 'getListUiByApiName',
    parameters: {
        required: ['objectApiName', 'listViewApiName'],
        optional: ['fields', 'optionalFields', 'pageSize', 'pageToken', 'sortBy']
    }
};
const getListUiByListViewId_ConfigPropertyNames = {
    displayName: 'getListUiByListViewId',
    parameters: {
        required: ['listViewId'],
        optional: ['fields', 'optionalFields', 'pageSize', 'pageToken', 'sortBy']
    }
};
const getMruListUi_ConfigPropertyNames = {
    displayName: 'getMruListUi',
    parameters: {
        required: ['objectApiName'],
        optional: ['fields', 'optionalFields', 'pageSize', 'pageToken', 'sortBy']
    }
};
// make local copies of the adapter configs so we can ignore other getListUi config parameters to match
// lds222 behavior
const getMruListUi_ConfigPropertyNames_augmented = {
    ...getMruListUi_ConfigPropertyNames,
    parameters: {
        ...getMruListUi_ConfigPropertyNames.parameters,
        optional: [
            ...getMruListUi_ConfigPropertyNames.parameters.optional,
            'listViewApiName',
            'listViewId',
        ],
    },
};
// make local copies of the adapter configs so we can have them ignore each other's config parameters
// to match lds222 behavior
const getListUiByApiName_ConfigPropertyNames_augmented = {
    ...getListUiByApiName_ConfigPropertyNames,
    parameters: {
        ...getListUiByApiName_ConfigPropertyNames.parameters,
        optional: [...getListUiByApiName_ConfigPropertyNames.parameters.optional, 'listViewId'],
    },
};
const getListUiByListViewId_ConfigPropertyNames_augmented = {
    ...getListUiByListViewId_ConfigPropertyNames,
    parameters: {
        ...getListUiByListViewId_ConfigPropertyNames.parameters,
        optional: [
            ...getListUiByListViewId_ConfigPropertyNames.parameters.optional,
            'listViewApiName',
            'objectApiName',
        ],
    },
};

const DEFAULT_MODE = LayoutMode.View;

var FormFactor;
(function (FormFactor) {
    FormFactor["Large"] = "Large";
    FormFactor["Medium"] = "Medium";
    FormFactor["Small"] = "Small";
})(FormFactor || (FormFactor = {}));

const select$e = function LeadStatusPicklistValueAttributesRepresentationSelect() {
    const { selections: AbstractPicklistValueAttributesRepresentationSelections } = select$h();
    return {
        kind: 'Fragment',
        selections: [
            ...AbstractPicklistValueAttributesRepresentationSelections,
            {
                name: 'converted',
                kind: 'Scalar',
            }
        ]
    };
};

const select$f = function CaseStatusPicklistValueAttributesRepresentationSelect() {
    const { selections: AbstractPicklistValueAttributesRepresentationSelections } = select$h();
    return {
        kind: 'Fragment',
        selections: [
            ...AbstractPicklistValueAttributesRepresentationSelections,
            {
                name: 'closed',
                kind: 'Scalar',
            }
        ]
    };
};

const select$g = function OpportunityStagePicklistValueAttributesRepresentationSelect() {
    const { selections: AbstractPicklistValueAttributesRepresentationSelections } = select$h();
    return {
        kind: 'Fragment',
        selections: [
            ...AbstractPicklistValueAttributesRepresentationSelections,
            {
                name: 'closed',
                kind: 'Scalar',
            },
            {
                name: 'defaultProbability',
                kind: 'Scalar',
            },
            {
                name: 'forecastCategoryName',
                kind: 'Scalar',
            },
            {
                name: 'won',
                kind: 'Scalar',
            }
        ]
    };
};
const selectChildren = function AbstractPicklistValueAttributesRepresentationSelectChildren(params) {
    const { selections: LeadStatusPicklistValueAttributesRepresentationSelections } = select$e();
    const { selections: CaseStatusPicklistValueAttributesRepresentationSelections } = select$f();
    const { selections: OpportunityStagePicklistValueAttributesRepresentationSelections } = select$g();
    return {
        kind: 'Object',
        name: params.propertyName,
        nullable: params.nullable,
        union: true,
        discriminator: 'picklistAtrributesValueType',
        unionSelections: {
            LeadStatus: LeadStatusPicklistValueAttributesRepresentationSelections,
            CaseStatus: CaseStatusPicklistValueAttributesRepresentationSelections,
            OpportunityStage: OpportunityStagePicklistValueAttributesRepresentationSelections
        }
    };
};
const select$h = function AbstractPicklistValueAttributesRepresentationSelect() {
    return {
        kind: 'Fragment',
        selections: [
            {
                name: 'picklistAtrributesValueType',
                kind: 'Scalar',
            }
        ]
    };
};
const select$i = function PicklistValueRepresentationSelect() {
    const AbstractPicklistValueAttributesRepresentation__unionSelections = selectChildren({
        propertyName: 'attributes',
        nullable: true
    });
    return {
        kind: 'Fragment',
        selections: [
            AbstractPicklistValueAttributesRepresentation__unionSelections,
            {
                name: 'label',
                kind: 'Scalar',
            },
            {
                name: 'validFor',
                kind: 'Scalar',
                plural: true,
            },
            {
                name: 'value',
                kind: 'Scalar',
            }
        ]
    };
};
const select$j = function PicklistValuesRepresentationSelect() {
    const { selections: PicklistValueRepresentation__selections, opaque: PicklistValueRepresentation__opaque, } = select$i();
    return {
        kind: 'Fragment',
        selections: [
            {
                name: 'controllerValues',
                kind: 'Scalar',
                map: true,
            },
            {
                name: 'defaultValue',
                kind: 'Object',
                nullable: true,
                selections: PicklistValueRepresentation__selections
            },
            {
                name: 'url',
                kind: 'Scalar',
            },
            {
                name: 'values',
                kind: 'Object',
                plural: true,
                selections: PicklistValueRepresentation__selections
            }
        ]
    };
};

const path = select$j().selections;

export { createRecordInputFilteredByEditedFields, generateRecordInputForCreate, generateRecordInputForUpdate, getFieldDisplayValue, getFieldValue, getRecordInput };
