Repository: adamgibbons/ics
Pull request #245 (2023-06-14 13:18:54)

Add support for transp attribute

boy51: +1

Patch:
diff --git a/README.md b/README.md
index cfa827b..d0d5f6a 100644
--- a/README.md
+++ b/README.md
@@ -273,6 +273,7 @@ The following properties are accepted:
 | recurrenceRule        | A recurrence rule, commonly referred to as an RRULE, defines the repeat pattern or rule for to-dos, journal entries and events. If specified, RRULE can be used to compute the recurrence set (the complete set of recurrence instances in a calendar component). You can use a generator like this [one](https://www.textmagic.com/free-tools/rrule-generator) | `FREQ=DAILY`
 | sequence      | For sending an update for an event (with the same uid), defines the revision sequence number. | `2`
 | busyStatus    | Used to specify busy status for Microsoft applications, like Outlook. See [Microsoft spec](https://docs.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxcical/cd68eae7-ed65-4dd3-8ea7-ad585c76c736). | `'BUSY'` OR `'FREE'` OR `'TENTATIVE`' OR `'OOF'`
+| transp        | Used to specify event transparency (does event consume actual time of an individual). Used by Google Calendar to determine if event should change attendees availability to 'Busy' or not. | `'TRANSPARENT'` OR `'OPAQUE'`
 | classification    | This property defines the access classification for a calendar component. See [iCalender spec](https://icalendar.org/iCalendar-RFC-5545/3-8-1-3-classification.html). | `'PUBLIC'` OR `'PRIVATE'` OR `'CONFIDENTIAL`' OR any non-standard string
 | created | Date-time representing event's creation date. Provide a date-time in UTC | [2000, 1, 5, 10, 0] (January 5, 2000 GMT +00:00)
 | lastModified | Date-time representing date when event was last modified. Provide a date-time in UTC | [2000, 1, 5, 10, 0] (January 5, 2000 GMT +00:00)
diff --git a/index.d.ts b/index.d.ts
index 572ab67..7193085 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -90,6 +90,7 @@ export type EventAttributes = {
   url?: string;
   status?: EventStatus;
   busyStatus?: 'FREE' | 'BUSY' | 'TENTATIVE' | 'OOF';
+  transp?: 'TRANSPARENT' | 'OPAQUE';
 
   organizer?: Person & {
     sentBy?: string;
diff --git a/notes.md b/notes.md
index 297c5fe..be96832 100644
--- a/notes.md
+++ b/notes.md
@@ -57,7 +57,7 @@ TZID=America/New_York:19980119T020000
 - [ ] seq
 - [x] status
 - [x] summary
-- [ ] transp
+- [x] transp
 - [x] url
 - [ ] recurid
 
diff --git a/src/pipeline/format.js b/src/pipeline/format.js
index c606cac..a587161 100644
--- a/src/pipeline/format.js
+++ b/src/pipeline/format.js
@@ -38,6 +38,7 @@ export default function formatEvent(attributes = {}) {
     alarms,
     recurrenceRule,
     busyStatus,
+    transp,
     classification,
     created,
     lastModified,
@@ -77,6 +78,7 @@ export default function formatEvent(attributes = {}) {
   icsFormat += categories ? (foldLine(`CATEGORIES:${categories}`) + '\r\n') : ''
   icsFormat += organizer ? (foldLine(`ORGANIZER;${setOrganizer(organizer)}`) + '\r\n') : ''
   icsFormat += busyStatus ? (foldLine(`X-MICROSOFT-CDO-BUSYSTATUS:${busyStatus}`) + '\r\n') : ''
+  icsFormat += transp ? (foldLine(`TRANSP:${transp}`) + '\r\n') : ''
   icsFormat += classification ? (foldLine(`CLASS:${classification}`) + '\r\n') : ''
   icsFormat += created ? ('CREATED:' + formatDate(created) + '\r\n') : ''
   icsFormat += lastModified ? ('LAST-MODIFIED:' + formatDate(lastModified) + '\r\n') : ''
diff --git a/src/schema/index.js b/src/schema/index.js
index 52f26a1..70458a1 100644
--- a/src/schema/index.js
+++ b/src/schema/index.js
@@ -87,6 +87,7 @@ const schema = yup.object().shape({
   alarms: yup.array().of(alarmSchema),
   recurrenceRule: yup.string(),
   busyStatus: yup.string().matches(/TENTATIVE|FREE|BUSY|OOF/i),
+  transp: yup.string().matches(/TRANSPARENT|OPAQUE/i),
   classification: yup.string(),
   created: dateTimeSchema,
   lastModified: dateTimeSchema,


Test patch:
diff --git a/test/pipeline/format.spec.js b/test/pipeline/format.spec.js
index d8cc7ae..dff01cc 100644
--- a/test/pipeline/format.spec.js
+++ b/test/pipeline/format.spec.js
@@ -192,6 +192,14 @@ describe('pipeline.formatEvent', () => {
     expect(formattedEventTent).to.contain('X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE')
     expect(formattedEventOOF).to.contain('X-MICROSOFT-CDO-BUSYSTATUS:OOF')
   })
+  it('writes a transp', () => {
+    const eventFree = buildEvent({ transp: "TRANSPARENT" })
+    const eventBusy = buildEvent({ transp: "OPAQUE"})
+    const formattedEventFree = formatEvent(eventFree)
+    const formattedEventBusy = formatEvent(eventBusy)
+    expect(formattedEventFree).to.contain('TRANSP:TRANSPARENT')
+    expect(formattedEventBusy).to.contain('TRANSP:OPAQUE')
+  })
   it('writes a access classification', () => {
     const eventPublic = buildEvent({ classification: "PUBLIC" })
     const eventPrivate = buildEvent({ classification: "PRIVATE"})
diff --git a/test/schema/index.spec.js b/test/schema/index.spec.js
index e5e79d0..deea7ee 100644
--- a/test/schema/index.spec.js
+++ b/test/schema/index.spec.js
@@ -220,6 +220,15 @@ describe('.validateEvent', () => {
       }).value.created).to.exist
     })
 
+    it('transp', () => {
+      expect(validateEvent({
+        title: 'foo',
+        uid: 'foo',
+        start: [2018, 12, 1, 10, 30],
+        transp: 'TRANSPARENT'
+      }).value.transp).to.exist
+    })
+
     it('lastModified', () => {
       expect(validateEvent({
         title: 'foo',