nylas / nylas-nodejs

A NodeJS wrapper for the Nylas REST API for email, contacts, and calendar.
MIT License
166 stars 116 forks source link

Type mismatch in Events - When DataType #550

Closed Leave-it-blank closed 3 months ago

Leave-it-blank commented 3 months ago

Describe the bug So I came across this bug, Inside the type of Event Object

Context.

  const events = await nylas.events.list({
            identifier: account.grant_id,
            queryParams: queryParams,
          });

type When = Time | Timespan | Date | Datespan;

export interface Time {
    /**
     * A UNIX timestamp representing the time of occurrence.
     */
    time: number;
    /**
     * If timezone is present, then the value for time will be read with timezone.
     * Timezone using IANA formatted string. (e.g. "America/New_York")
     * @see <a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">List of tz database time zones</a>
     */
    timezone: string;
    /**
     * The type of 'when' object.
     */
    type: WhenType.Time;
}
export interface Timespan {
    /**
     * The start time of the event.
     */
    startTime: number;
    /**
     * The end time of the event.
     */
    endTime: number;
    /**
     * The timezone of the start time.
     * Timezone using IANA formatted string. (e.g. "America/New_York")
     * @see <a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">List of tz database time zones</a>
     */
    startTimezone?: string;
    /**
     * The timezone of the end time.
     * Timezone using IANA formatted string. (e.g. "America/New_York")
     * @see <a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">List of tz database time zones</a>
     */
    endTimezone?: string;
    /**
     * The type of 'when' object.
     */
    type: WhenType.Timespan;
}

So problem aries as documentation for V3 Api mentions that it will return an

"object" instead of "type" inside When dataType of Event.

ANY OF These
Timespan {
    start_time: number
    end_time: number
   start_timezone: string or null
   end_timezone: string or null
   object: string πŸ† timespan Default: timespan
}

 Date { 
      date: string
      object: string πŸ† Default: date
}

Datespan {
      start_date: string
      end_date: string
     object: string πŸ† Default: datespan
}

In conclusion, there is a type mismatch between sdk & api doc. As api actually returns "object" instead of "type".

To Reproduce Not sure? Just look at sdk type for Event https://github.com/nylas/nylas-nodejs/blob/main/src/models/events.ts https://developer.nylas.com/docs/api/v3/ecc/#get-/v3/grants/-grant_id-/events

Expected behavior Need to update event.ts file to match api docs type.

SDK Version: "nylas": "^7.2.1", "I am using V3 api"

Additional context I switched to sdk to avoid type mismatch between my codebase & nylas, if its fine then I can quickly update the types in repo and open PR.

relaxedtomato commented 3 months ago

Hi @Leave-it-blank - just taking a look at this, just to confirm my understanding what is the proposed change? Would it be updating the types?

Is it that the when property doesn't match what's returned by the API? If so, can you clarify this further, what is the expected outcome?

So problem aries as documentation for V3 Api mentions that it will return an "object" instead of "type" inside When dataType of Event.

Is it the fact that the properties are not consistent? So taking one property from Timespan like startTime, it should be start_time to match the API docs response?

Leave-it-blank commented 3 months ago

@relaxedtomato Yes, Types are mismatching.

=> "type" proprty inside when should be "object" according to API response inside When Type => missing optional property "masterEventId" , "originalStartTime" in Event Type

API RESPONSE:

{
    busy: true,
    calendarId: 'primary',
    conferencing: {},
    description: 'Come ready to skate',
    hideParticipants: false,
    icalUid: 'uloflpfhf0qhohk1c@google.com',
    location: 'Roller Rink',
    organizer: { name: '', email: 'mayank@m0.ventures' },
    participants: [ [Object] ],
    readOnly: false,
    reminders: { useDefault: true, overrides: null },
    title: 'Birthday Party',
    visibility: 'default',
    creator: { name: '', email: 'mayank@m0.ventures' },
    htmlLink: 'https://www.google.com/calendar/event?eid=dWxvZmxwZevent,
    masterEventId: 'uloflpfhf0qhodrsg60uq1hk1c',
    grantId: '9858771e-grant',
    id: 'uloflpfhf0qid',
    object: 'event',
    status: 'confirmed',
    when: {
      startTimezone: 'America/New_York',
      endTimezone: 'America/New_York',
      **object: 'timespan',**
      startTime: 1713186000,
      endTime: 1713186000
    },
    createdAt: 1708097389,
    updatedAt: 1708097389,
    originalStartTime: 1713186000
  }

Expected outcome, is to update the "type" to "object" and add missing properties inside Event Type as optional

Leave-it-blank commented 3 months ago

Also, Typescript is not able to pick up on conferencing datatype when creating an instant meeting.

 const event = await nylas.events.create({
          identifier: account.grant_id,
          requestBody: {
            title: input.title,
            when: {
              date: moment(new Date()).format("yyyy-MM-DD"),
            },
            participants: emails,
            busy: input.busy,
            capacity: input.capacity,
            description: input.description,
            location: input.location,
            reminders: {
              useDefault: input.reminder,
              overrides: [],
            },
            conferencing: {
              provider: "Google Meet",
              autocreate: { enabled: true },
            },
            metadata: {
              eventType: "instant_meeting",
              bgColorHex: "#1B222B",
              textColorHex: "#FFFFFF",
            },
            hideParticipants: input.hide_participants,
          },
          queryParams: {
            calendarId: "primary",
          },
        });
   ` ((event.data.conferencing as Conferencing)?.details as Details).details`
   * error Conferencing is not exported member of "nylas"

   So unable to assert type on it either. 
Screenshot 2024-03-22 at 1 13 28β€―PM

API RESPONSE:


Insta Meet Event: {
  requestId: 'c514d91d-c85c-4d69-bfa2-ada',
  data: {
    busy: true,
    calendarId: 'primary',
    capacity: 100,
    conferencing: { provider: 'Google Meet', details: [Object] },
    description: 'Instant Meeting generated via quick action.',
    hideParticipants: false,
    icalUid: 'ad@google.com',
    location: 'Online',
    metadata: {
      bgColorHex: '#1B222B',
      eventType: 'instant_meeting',
      textColorHex: '#FFFFFF'
    },
    organizer: { name: '', email: 'mayank@m0.ventures' },
    participants: [ [Object] ],
    readOnly: false,
    reminders: { useDefault: false, overrides: [Array] },
    title: 'Instant Meeting',
    visibility: 'default',
    creator: { name: '', email: 'mayank@m0.ventures' },
    htmlLink: 'https://www.google.com/calendar/event?eid=da',
    grantId: '9858771e-ad-ad-bb04-ad',
    id: 'adadadadad',
    object: 'event',
    status: 'confirmed',
    when: { date: '2024-03-22', object: 'date' },
    createdAt: 1711092896,
    updatedAt: 1711092896
  }
}
Leave-it-blank commented 3 months ago

So I came across more mismatch in Event creation,

In SDK: type ConferencingProvider = 'Google Meet' | 'Zoom Meeting' | 'Microsoft Teams' | 'GoToMeeting' | 'WebEx';

API RESPONSE: NylasApiError: conference.provider must be one of: ['Google Meet','Microsoft Teams','Zoom Meeting','teamsForBusiness'] at APIClient.sendRequest (webpack-internal:///(rsc)/./node_modules/nylas/lib/esm/apiClient.js:81:33) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async APIClient.request (webpack-internal:///(rsc)/./node_modules/nylas/lib/esm/apiClient.js:133:26) at async eval (webpack-internal:///(rsc)/./src/server/api/routers/nylas-sdk/calendar-router.ts:217:27) at async resolveMiddleware (webpack-internal:///(rsc)/./node_modules/@trpc/server/dist/index.mjs:441:30) at async callRecursive (webpack-internal:///(rsc)/./node_modules/@trpc/server/dist/index.mjs:471:32) at async callRecursive (webpack-internal:///(rsc)/./node_modules/@trpc/server/dist/index.mjs:471:32) at async callRecursive (webpack-internal:///(rsc)/./node_modules/@trpc/server/dist/index.mjs:471:32) at async resolve (webpack-internal:///(rsc)/./node_modules/@trpc/server/dist/index.mjs:501:24) at async inputToProcedureCall (webpack-internal:///(rsc)/./node_modules/@trpc/server/dist/resolveHTTPResponse-2fc435bb.mjs:55:22) at async resolveHTTPResponse (webpack-internal:///(rsc)/./node_modules/@trpc/server/dist/resolveHTTPResponse-2fc435bb.mjs:238:49) { type: 'invalid_request_error', requestId: '82e03a15-2a71-4de2-a51d-f278819e74d0', providerError: undefined, statusCode: 400 }

Expected Change: inside Event.ts -> modals type ConferencingProvider = 'Google Meet' | 'Microsoft Teams' | 'Zoom Meeting' | 'teamsForBusiness'

relaxedtomato commented 3 months ago

@Leave-it-blank thanks for the feedback, our SDK team is going to take a look at this ticket further next, and I see that we have an open PR for the following update:

Expected outcome, is to update the "type" to "object"

mrashed-dev commented 3 months ago

Thanks for reporting this issue @Leave-it-blank! You look correct; there's definitely a mismatch between the schema and the TS interfaces here. I see @hanut has submitted a PR that should address this. I'll take a look and if it's all good we'll include it in the upcoming release.