@littlebearapps/outlook-assistant 3.5.2 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/utils/safety.js CHANGED
@@ -116,8 +116,121 @@ function formatDryRunPreview(emailObject) {
116
116
  };
117
117
  }
118
118
 
119
+ /**
120
+ * Format a dry-run preview for a mail rule (create or update).
121
+ * @param {object} rule - The composed Graph API rule object
122
+ * @returns {string} - Human-readable rule preview text
123
+ */
124
+ function formatRuleDryRunPreview(rule) {
125
+ const lines = [];
126
+
127
+ lines.push(`Name: ${rule.displayName}`);
128
+ lines.push(`Enabled: ${rule.isEnabled !== false}`);
129
+ if (rule.sequence) lines.push(`Sequence: ${rule.sequence}`);
130
+
131
+ // Conditions
132
+ const cond = rule.conditions || {};
133
+ const condParts = [];
134
+ if (cond.fromAddresses?.length > 0) {
135
+ condParts.push(
136
+ `From: ${cond.fromAddresses.map((a) => a.emailAddress?.address).join(', ')}`
137
+ );
138
+ }
139
+ if (cond.subjectContains?.length > 0) {
140
+ condParts.push(
141
+ `Subject contains (any): "${cond.subjectContains.join('", "')}"`
142
+ );
143
+ }
144
+ if (cond.bodyContains?.length > 0) {
145
+ condParts.push(`Body contains (any): "${cond.bodyContains.join('", "')}"`);
146
+ }
147
+ if (cond.bodyOrSubjectContains?.length > 0) {
148
+ condParts.push(
149
+ `Body or subject contains (any): "${cond.bodyOrSubjectContains.join('", "')}"`
150
+ );
151
+ }
152
+ if (cond.senderContains?.length > 0) {
153
+ condParts.push(
154
+ `Sender contains (any): "${cond.senderContains.join('", "')}"`
155
+ );
156
+ }
157
+ if (cond.recipientContains?.length > 0) {
158
+ condParts.push(
159
+ `Recipient contains (any): "${cond.recipientContains.join('", "')}"`
160
+ );
161
+ }
162
+ if (cond.sentToAddresses?.length > 0) {
163
+ condParts.push(
164
+ `Sent to: ${cond.sentToAddresses.map((a) => a.emailAddress?.address).join(', ')}`
165
+ );
166
+ }
167
+ if (cond.hasAttachment === true) condParts.push('Has attachment');
168
+ if (cond.importance) condParts.push(`Importance: ${cond.importance}`);
169
+ if (cond.sensitivity) condParts.push(`Sensitivity: ${cond.sensitivity}`);
170
+ if (cond.sentToMe === true) condParts.push('Sent to me');
171
+ if (cond.sentOnlyToMe === true) condParts.push('Sent only to me');
172
+ if (cond.sentCcMe === true) condParts.push('I am in CC');
173
+ if (cond.isAutomaticReply === true) condParts.push('Is automatic reply');
174
+ if (condParts.length > 0) {
175
+ lines.push(`Conditions: ${condParts.join('; ')}`);
176
+ }
177
+
178
+ // Actions
179
+ const act = rule.actions || {};
180
+ const actParts = [];
181
+ if (act.moveToFolder) actParts.push(`Move to folder: ${act.moveToFolder}`);
182
+ if (act.copyToFolder) actParts.push(`Copy to folder: ${act.copyToFolder}`);
183
+ if (act.markAsRead === true) actParts.push('Mark as read');
184
+ if (act.markImportance) {
185
+ actParts.push(`Mark importance: ${act.markImportance}`);
186
+ }
187
+ if (act.forwardTo?.length > 0) {
188
+ actParts.push(
189
+ `Forward to: ${act.forwardTo.map((r) => r.emailAddress?.address).join(', ')}`
190
+ );
191
+ }
192
+ if (act.redirectTo?.length > 0) {
193
+ actParts.push(
194
+ `Redirect to: ${act.redirectTo.map((r) => r.emailAddress?.address).join(', ')}`
195
+ );
196
+ }
197
+ if (act.assignCategories?.length > 0) {
198
+ actParts.push(`Assign categories: ${act.assignCategories.join(', ')}`);
199
+ }
200
+ if (act.stopProcessingRules === true) actParts.push('Stop processing rules');
201
+ if (act.delete === true) actParts.push('Delete (move to Deleted Items)');
202
+ if (actParts.length > 0) {
203
+ lines.push(`Actions: ${actParts.join('; ')}`);
204
+ }
205
+
206
+ // Exceptions
207
+ const exc = rule.exceptions || {};
208
+ const excParts = [];
209
+ if (exc.fromAddresses?.length > 0) {
210
+ excParts.push(
211
+ `From: ${exc.fromAddresses.map((a) => a.emailAddress?.address).join(', ')}`
212
+ );
213
+ }
214
+ if (exc.subjectContains?.length > 0) {
215
+ excParts.push(`Subject contains: "${exc.subjectContains.join('", "')}"`);
216
+ }
217
+ if (exc.senderContains?.length > 0) {
218
+ excParts.push(`Sender contains: "${exc.senderContains.join('", "')}"`);
219
+ }
220
+ if (exc.bodyContains?.length > 0) {
221
+ excParts.push(`Body contains: "${exc.bodyContains.join('", "')}"`);
222
+ }
223
+ if (exc.hasAttachment === true) excParts.push('Has attachment');
224
+ if (excParts.length > 0) {
225
+ lines.push(`Exceptions (rule skipped when): ${excParts.join('; ')}`);
226
+ }
227
+
228
+ return lines.join('\n');
229
+ }
230
+
119
231
  module.exports = {
120
232
  checkRateLimit,
121
233
  checkRecipientAllowlist,
122
234
  formatDryRunPreview,
235
+ formatRuleDryRunPreview,
123
236
  };