Repository: adamgibbons/ics
Pull request #230 (2022-12-13 11:22:23)

Add SENT-BY property to organizer
There is a "SENT-BY" property that can be added to the organizer of an event. The sent by email is the person acting on behalf of the organizer. 

In this PR, I've added that value to the organizer and updated the organizer test to include both "dir" and "sentBy"


Patch:
diff --git a/README.md b/README.md
index bbae996..8be3154 100644
--- a/README.md
+++ b/README.md
@@ -263,7 +263,7 @@ The following properties are accepted:
 | geo   | Geographic coordinates (lat/lon) | `{ lat: 38.9072, lon: 77.0369 }`
 | url           | URL associated with event | `'http://www.mountainsunpub.com/'`
 | status        | Three statuses are allowed: `TENTATIVE`, `CONFIRMED`, `CANCELLED` | `CONFIRMED`
-| organizer     | Person organizing the event | `{ name: 'Adam Gibbons', email: 'adam@example.com', dir: 'https://linkedin.com/in/adamgibbons' }`
+| organizer     | Person organizing the event | `{ name: 'Adam Gibbons', email: 'adam@example.com', dir: 'https://linkedin.com/in/adamgibbons', sentBy: 'test@example.com' }`
 | attendees     | Persons invited to the event | `[{ name: 'Mo', email: 'mo@foo.com', rsvp: true }, { name: 'Bo', email: 'bo@bar.biz', dir: 'https://twitter.com/bo1234', partstat: 'ACCEPTED', role: 'REQ-PARTICIPANT' }]`
 | categories    | Categories associated with the event | `['hacknight', 'stout month']`
 | alarms        | Alerts that can be set to trigger before, during, or after the event. The following `attach` properties work on Mac OS: Basso, Blow, Bottle, Frog, Funk, Glass, Hero, Morse, Ping, Pop, Purr, Sousumi, Submarine, Tink | `{ action: 'display', description: 'Reminder', trigger: [2000, 1, 4, 18, 30] }` OR `{ action: 'display', description: 'Reminder', trigger: { hours: 2, minutes: 30, before: true } }` OR `{ action: 'display', description: 'Reminder', trigger: { hours: 2, minutes: 30, before: false }` OR `{ action: 'audio', description: 'Reminder', trigger: { hours: 2, minutes: 30, before: true }, repeat: 2, attachType: 'VALUE=URI', attach: 'Glass' }`
diff --git a/index.d.ts b/index.d.ts
index 1bb7295..809a995 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -82,7 +82,9 @@ export type EventAttributes = {
   status?: EventStatus;
   busyStatus?: 'FREE' | 'BUSY' | 'TENTATIVE' | 'OOF';
   
-  organizer?: Person;
+  organizer?: Person & {
+    sentBy?: string;
+  };
   attendees?: Attendee[];
   
   categories?: string[];
diff --git a/src/schema/index.js b/src/schema/index.js
index 4c5e35c..2c81391 100644
--- a/src/schema/index.js
+++ b/src/schema/index.js
@@ -40,7 +40,8 @@ const contactSchema = yup.object().shape({
 const organizerSchema = yup.object().shape({
   name: yup.string(),
   email: yup.string().email(),
-  dir: yup.string()
+  dir: yup.string(),
+  sentBy: yup.string()
 }).noUnknown()
 
 const alarmSchema = yup.object().shape({
diff --git a/src/utils/set-organizer.js b/src/utils/set-organizer.js
index b63e6ec..26adf00 100644
--- a/src/utils/set-organizer.js
+++ b/src/utils/set-organizer.js
@@ -1,9 +1,10 @@
-export default function setOrganizer({ name, email, dir }) {
+export default function setOrganizer({ name, email, dir, sentBy }) {
   let formattedOrganizer = ''
   formattedOrganizer += dir ? `DIR="${dir}";` : ''
+  formattedOrganizer += sentBy ? `SENT-BY="MAILTO:${sentBy}";` : ''
   formattedOrganizer += 'CN='
   formattedOrganizer += name || 'Organizer'
-  formattedOrganizer += email ? `:mailto:${email}` : ''
+  formattedOrganizer += email ? `:MAILTO:${email}` : ''
 
   return formattedOrganizer
 }


Test patch:
diff --git a/test/pipeline/format.spec.js b/test/pipeline/format.spec.js
index d1ca25f..7aebc41 100644
--- a/test/pipeline/format.spec.js
+++ b/test/pipeline/format.spec.js
@@ -4,6 +4,7 @@ import {
   formatEvent,
   buildEvent
 } from '../../src/pipeline'
+import {foldLine} from "../../src/utils";
 
 describe('pipeline.formatEvent', () => {
   it('writes default values when no attributes passed', () => {
@@ -206,12 +207,13 @@ describe('pipeline.formatEvent', () => {
     expect(formattedEventAnyClass).to.contain('CLASS:non-standard-property')
   })
   it('writes an organizer', () => {
-    const event = formatEvent({ organizer: {
-      name: 'Adam Gibbons',
-      email: 'adam@example.com'
-    }})
-    const formattedEvent = formatEvent(event)
-    expect(event).to.contain('ORGANIZER;CN=Adam Gibbons:mailto:adam@example.com')
+    const formattedEvent = formatEvent({ organizer: {
+        name: 'Adam Gibbons',
+        email: 'adam@example.com',
+        dir: 'test-dir-value',
+        sentBy: 'test@example.com'
+      }})
+    expect(formattedEvent).to.contain(foldLine('ORGANIZER;DIR="test-dir-value";SENT-BY="MAILTO:test@example.com";CN=Adam Gibbons:MAILTO:adam@example.com'))
   })
   it('writes an alarm', () => {
     const formattedEvent = formatEvent({ alarms: [{