<commit_before>// -------------------------------------------------------------------------- \\
// File: MessageSubmission.js                                                 \\
// Module: MailModel                                                          \\
// Requires: API, Message.js, Thread.js, Identity.js                          \\
// -------------------------------------------------------------------------- \\

/*global O, JMAP */

'use strict';

( function ( JMAP, undefined ) {

var Record = O.Record;
var attr = Record.attr;

var Identity = JMAP.Identity;
var Message = JMAP.Message;
var Thread = JMAP.Thread;
var makeSetRequest = JMAP.Connection.makeSetRequest;

// ---

var MessageSubmission = O.Class({

    Extends: Record,

    identity: Record.toOne({
        Type: Identity,
        key: 'identityId',
    }),

    message: Record.toOne({
        Type: Message,
        key: 'messageId',
    }),

    thread: Record.toOne({
        Type: Thread,
        key: 'threadId',
        noSync: true,
    }),

    envelope: attr( Object, {
        defaultValue: null,
    }),

    sendAt: attr( Date, {
        noSync: true,
    }),

    undoStatus: attr( String, {
        noSync: true,
        defaultValue: 'pending',
    }),

    deliveryStatus: attr( Object, {
        noSync: true,
        defaultValue: null,
    }),

    dsnBlobIds: attr( Array ),
    mdnBlobIds: attr( Array ),

    // ---

    // Not a real JMAP property; stripped before sending to server.
    onSuccess: attr( Object ),
});

MessageSubmission.makeEnvelope = function ( message ) {
    var sender = message.get( 'sender' );
    var mailFrom = {
        email: sender ?
            sender.email :
            message.get( 'fromEmail' ),
        parameters: null,
    };
    var seen = {};
    var rcptTo = [ 'to', 'cc', 'bcc' ].reduce( function ( rcptTo, header ) {
        var addresses = message.get( header );
        if ( addresses ) {
            addresses.forEach( function ( address ) {
                var email = address.email;
                if ( email && !seen[ email ] ) {
                    seen[ email ] = true;
                    rcptTo.push({ email: email, parameters: null });
                }
            });
        }
        return rcptTo;
    }, [] );
    return {
        mailFrom: mailFrom,
        rcptTo: rcptTo,
    };
};


JMAP.mail.handle( MessageSubmission, {
    precedence: 3,
    fetch: function ( ids ) {
        this.callMethod( 'getMessageSubmissions', {
            ids: ids || [],
        });
    },

    refresh: function ( ids, state ) {
        if ( ids ) {
            this.callMethod( 'getMessageSubmissions', {
                ids: ids,
            });
        } else {
            this.callMethod( 'getMessageSubmissionUpdates', {
                sinceState: state,
                maxChanges: 50,
                fetchRecords: true,
            });
        }
    },
    commit: function ( change ) {
        var store = this.get( 'store' );
        var args = makeSetRequest( change );

        // TODO: Prevent double sending if dodgy connection
        // if ( Object.keys( args.create ).length ) {
        //     args.ifInState = change.state;
        // }

        var onSuccessUpdateMessage = {};
        var onSuccessDestroyMessage = {};
        var create = args.create;
        var update = args.update;
        var id, submission;

        var draftsId = this.getMailboxIdForRole( 'drafts' );
        var sentId = this.getMailboxIdForRole( 'sent' );
        var updateMessage = {};
        updateMessage[ 'mailboxIds.' + sentId ] = null;
        updateMessage[ 'mailboxIds.' + draftsId ] = true;
        updateMessage[ 'keywords.$Draft' ] = true;

        // On create move from drafts, remove $Draft keyword
        for ( id in create ) {
            submission = create[ id ];
            if ( submission.onSuccess === null ) {
                args.onSuccessDestroyMessage = onSuccessDestroyMessage;
                onSuccessDestroyMessage.push( '#' + id );
            } else if ( submission.onSuccess ) {
                args.onSuccessUpdateMessage = onSuccessUpdateMessage;
                onSuccessUpdateMessage[ '#' + id ] = submission.onSuccess;<commit_msg>Fix JSON pointer syntax error<commit_after>// -------------------------------------------------------------------------- \\
// File: MessageSubmission.js                                                 \\
// Module: MailModel                                                          \\
// Requires: API, Message.js, Thread.js, Identity.js                          \\
// -------------------------------------------------------------------------- \\

/*global O, JMAP */

'use strict';

( function ( JMAP, undefined ) {

var Record = O.Record;
var attr = Record.attr;

var Identity = JMAP.Identity;
var Message = JMAP.Message;
var Thread = JMAP.Thread;
var makeSetRequest = JMAP.Connection.makeSetRequest;

// ---

var MessageSubmission = O.Class({

    Extends: Record,

    identity: Record.toOne({
        Type: Identity,
        key: 'identityId',
    }),

    message: Record.toOne({
        Type: Message,
        key: 'messageId',
    }),

    thread: Record.toOne({
        Type: Thread,
        key: 'threadId',
        noSync: true,
    }),

    envelope: attr( Object, {
        defaultValue: null,
    }),

    sendAt: attr( Date, {
        noSync: true,
    }),

    undoStatus: attr( String, {
        noSync: true,
        defaultValue: 'pending',
    }),

    deliveryStatus: attr( Object, {
        noSync: true,
        defaultValue: null,
    }),

    dsnBlobIds: attr( Array ),
    mdnBlobIds: attr( Array ),

    // ---

    // Not a real JMAP property; stripped before sending to server.
    onSuccess: attr( Object ),
});

MessageSubmission.makeEnvelope = function ( message ) {
    var sender = message.get( 'sender' );
    var mailFrom = {
        email: sender ?
            sender.email :
            message.get( 'fromEmail' ),
        parameters: null,
    };
    var seen = {};
    var rcptTo = [ 'to', 'cc', 'bcc' ].reduce( function ( rcptTo, header ) {
        var addresses = message.get( header );
        if ( addresses ) {
            addresses.forEach( function ( address ) {
                var email = address.email;
                if ( email && !seen[ email ] ) {
                    seen[ email ] = true;
                    rcptTo.push({ email: email, parameters: null });
                }
            });
        }
        return rcptTo;
    }, [] );
    return {
        mailFrom: mailFrom,
        rcptTo: rcptTo,
    };
};


JMAP.mail.handle( MessageSubmission, {
    precedence: 3,
    fetch: function ( ids ) {
        this.callMethod( 'getMessageSubmissions', {
            ids: ids || [],
        });
    },

    refresh: function ( ids, state ) {
        if ( ids ) {
            this.callMethod( 'getMessageSubmissions', {
                ids: ids,
            });
        } else {
            this.callMethod( 'getMessageSubmissionUpdates', {
                sinceState: state,
                maxChanges: 50,
                fetchRecords: true,
            });
        }
    },
    commit: function ( change ) {
        var store = this.get( 'store' );
        var args = makeSetRequest( change );

        // TODO: Prevent double sending if dodgy connection
        // if ( Object.keys( args.create ).length ) {
        //     args.ifInState = change.state;
        // }

        var onSuccessUpdateMessage = {};
        var onSuccessDestroyMessage = {};
        var create = args.create;
        var update = args.update;
        var id, submission;

        var draftsId = this.getMailboxIdForRole( 'drafts' );
        var sentId = this.getMailboxIdForRole( 'sent' );
        var updateMessage = {};
        updateMessage[ 'mailboxIds/' + sentId ] = null;
        updateMessage[ 'mailboxIds/' + draftsId ] = true;
        updateMessage[ 'keywords/$Draft' ] = true;

        // On create move from drafts, remove $Draft keyword
        for ( id in create ) {
            submission = create[ id ];
            if ( submission.onSuccess === null ) {
                args.onSuccessDestroyMessage = onSuccessDestroyMessage;
                onSuccessDestroyMessage.push( '#' + id );
            } else if ( submission.onSuccess ) {
                args.onSuccessUpdateMessage = onSuccessUpdateMessage;
                onSuccessUpdateMessage[ '#' + id ] = submission.onSuccess;
{'fraction_non_alphanumeric': 0.15308056872037915, 'fraction_numerical': 0.0007109004739336493, 'mean_word_length': 1.4702955809189346, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1986246', 'n_tokens_mistral': 2285, 'n_tokens_neox': 2215, 'n_words': 563}