Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,16 @@
"types": "./dist/governance/index.d.ts",
"default": "./dist/governance/index.cjs"
}
},
"./notifications": {
"import": {
"types": "./dist/notifications/index.d.ts",
"default": "./dist/notifications/index.mjs"
},
"require": {
"types": "./dist/notifications/index.d.ts",
"default": "./dist/notifications/index.cjs"
}
}
},
"files": [
Expand Down
5 changes: 5 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@ const serviceEntries = [
name: 'governance',
input: 'src/services/governance/index.ts',
output: 'governance/index'
},
{
name: 'notifications',
input: 'src/services/notification/index.ts',
output: 'notifications/index'
}
];

Expand Down
6 changes: 6 additions & 0 deletions src/models/notification/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Notification models barrel export.
*/

export * from './notifications.types';
export * from './notifications.models';
9 changes: 9 additions & 0 deletions src/models/notification/notifications.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Notification field mappings (API field name → SDK field name).
*
* Semantic renames only — case conversion is handled by `pascalToCamelCaseKeys()`
* (not needed here, the API already returns camelCase).
*/
export const NotificationMap: { [key: string]: string } = {
isRead: 'hasRead',
Comment on lines +7 to +8

@Sarath1018 Sarath1018 Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: why this transformation? hasRead looks good but why have you selected to change only this field, Is this decided by your team?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it was a ask from @vnaren23 to rename the field.

};
40 changes: 40 additions & 0 deletions src/models/notification/notifications.internal-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Internal-only types for the Notification service.
*
* NOT exported from the public barrel (`src/models/notification/index.ts`).
*/

import type { NotificationGetResponse } from './notifications.types';

/**
* Raw notification entry shape as returned by `/odata/v1/NotificationEntry` — uses the
* API's `isRead` field (renamed to `hasRead` in the SDK response) and includes the
* internal/transport-layer fields the SDK drops before returning to consumers.
*/
export interface RawNotificationEntry extends Omit<NotificationGetResponse, 'hasRead'> {

@Sarath1018 Sarath1018 Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Raw API response its fine to duplicate the fields as we do in other places, Deriving the raw type by taking the SDK response and modifying it is not a good practice

/** API read flag — renamed to `hasRead` in {@link NotificationGetResponse}. */
isRead: boolean;
entityOrgName?: string | null;
entityTenantName?: string | null;
serviceRegistryName?: string | null;
messageTemplateKey?: string | null;
messageVersion?: number;
publicationId?: string;
correlationId?: string | null;
partitionKey?: string;
}

/**
* Fields stripped from each {@link RawNotificationEntry} before it is returned to the
* SDK consumer as a {@link NotificationGetResponse}.
*/
export const INTERNAL_NOTIFICATION_FIELDS = [
'entityOrgName',
'entityTenantName',
'serviceRegistryName',
'messageTemplateKey',
'messageVersion',
'publicationId',
'correlationId',
'partitionKey',
] as const satisfies ReadonlyArray<keyof RawNotificationEntry>;
69 changes: 69 additions & 0 deletions src/models/notification/notifications.models.ts
Comment thread
sarthak688 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* Notification service model — public response shapes and the ServiceModel interface
* that drives generated API documentation.
*/

import type {
HasPaginationOptions,
NonPaginatedResponse,
PaginatedResponse,
} from '../../utils/pagination/types';

import type {
NotificationGetAllOptions,
NotificationGetResponse,
} from './notifications.types';

/**
* Public surface of the Notifications service. JSDoc on this interface drives
* the generated API reference documentation.
*
* Every method takes the tenant GUID as the first argument — the notification
* API identifies the acting tenant via the `X-UIPATH-Internal-TenantId` header
* and the SDK forwards `tenantId` into that header on each call.
*/
export interface NotificationServiceModel {
/**
* Lists notifications from the current user's inbox.
*
* Returns the full list when no pagination params are provided, or a paginated cursor result
* when any of `pageSize`/`cursor`/`jumpToPage` is supplied. Supports OData `filter` and
* `orderby` query options.
*
* @param tenantId - Tenant GUID (sent via `X-UIPATH-Internal-TenantId`)
* @returns Promise resolving to either a {@link NonPaginatedResponse}<{@link NotificationGetResponse}> or a {@link PaginatedResponse}<{@link NotificationGetResponse}> when pagination options are used.
*
* @example Basic usage
* ```typescript
* import { Notifications } from '@uipath/uipath-typescript/notifications';
*
* const notifications = new Notifications(sdk);
* const all = await notifications.getAll('<tenantId>');
* ```
*
* @example Filter unread, most recent first
* ```typescript
* const unread = await notifications.getAll('<tenantId>', {
* filter: 'hasRead eq false',
* orderby: 'publishedOn desc',
* });
* ```
*
* @example First page with pagination
* ```typescript
* const page1 = await notifications.getAll('<tenantId>', { pageSize: 20 });
* if (page1.hasNextPage) {
* const page2 = await notifications.getAll('<tenantId>', { cursor: page1.nextCursor });
* }
* ```
* @internal
Comment thread
sarthak688 marked this conversation as resolved.
*/
getAll<T extends NotificationGetAllOptions = NotificationGetAllOptions>(
tenantId: string,
options?: T
): Promise<
T extends HasPaginationOptions<T>
? PaginatedResponse<NotificationGetResponse>
: NonPaginatedResponse<NotificationGetResponse>
>;
}
86 changes: 86 additions & 0 deletions src/models/notification/notifications.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* Notification inbox types — raw API shapes and request/response options.
*/

import type { RequestOptions } from '../common/types';
import type { PaginationOptions } from '../../utils/pagination/types';
Comment thread
sarthak688 marked this conversation as resolved.

/**
* Priority level assigned to a notification by the publisher.
*/
export enum NotificationPriority {
Low = 'Low',
Medium = 'Medium',
High = 'High',
Critical = 'Critical',
}

/**
* Severity classification of a notification topic.
*/
export enum NotificationCategory {
/** Informational — no action required. */
Info = 'Info',
/** Successful operation completed. */
Success = 'Success',
/** Warning — degraded behaviour or non-fatal issue. */
Warn = 'Warn',
/** Error — operation failed but the system continues. */
Error = 'Error',
/** Fatal — unrecoverable failure. */
Fatal = 'Fatal',
}

/**
* Notification entry as returned by `GET /odata/v1/NotificationEntry`.
*
* Field selection: many internal/transport-layer fields (`partitionKey`, `correlationId`,
* `publicationId`, `messageVersion`, `messageTemplateKey`, `serviceRegistryName`,
* `entityOrgName`, `entityTenantName`) are returned by the API but dropped from the SDK
* because they have no use for an application developer.
*/
export interface NotificationGetResponse {
/** Notification GUID. */
id: string;
/** Resolved notification message text. */
message: string | null;
/** Whether the user has read this notification. */
hasRead: boolean;
/** Name of the publisher (e.g. `Orchestrator`, `Actions`). */
publisherName: string;
/** Publisher GUID. */
publisherId: string;
/** Human-readable topic name. */
topicName: string;
/** Stable topic identifier (e.g. `Process.JobExecution.Faulted`). */
topicKeyName: string;
/** Topic GUID. */
topicId: string;
/** GUID of the user this notification belongs to (returned uppercase by the API). */
userId: string;
/** Email of the user. Often `null`. */
userEmail: string | null;
/** Tenant GUID this notification belongs to. Often `null` for org-scoped notifications. */
tenantId: string | null;
/** Notification priority. */
priority: NotificationPriority;
/** Notification severity category. */
category: NotificationCategory;
/** JSON string of template parameters — parse with `JSON.parse()`. May be `null`. */
messageParam: string | null;
/** URL to navigate to when the notification is clicked. */
redirectionUrl: string | null;
/** Unix epoch **seconds** when the notification was published. */
publishedOn: number;
}

/**
* Options for `Notifications.getAll()`.
*
* Supports OData query options (`filter`, `orderby`) and SDK cursor pagination.
*
* Notes:
* - `$select` and `$expand` are not exposed because the API returns 500 on `$select`
* and there are no expandable relationships on this endpoint.
*/
export type NotificationGetAllOptions = Omit<RequestOptions, 'expand' | 'select'> & PaginationOptions;
29 changes: 29 additions & 0 deletions src/services/notification/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Notification Service Module
*
* Provides access to the UiPath Notification platform from the perspective of an
* authenticated user (UserContext):
* - `Notifications` — list operations on the user's inbox (further operations land in
* follow-up PRs)
*
* Publishing (sending) notifications is a first-party service action and is NOT part of this module.
*
* @example
* ```typescript
* import { UiPath } from '@uipath/uipath-typescript/core';
* import { Notifications } from '@uipath/uipath-typescript/notifications';
*
* const sdk = new UiPath(config);
* await sdk.initialize();
*
* const notifications = new Notifications(sdk);
* const unread = await notifications.getAll('<tenantId>', { filter: 'isRead eq false' });
* ```
*
* @module
*/

export { NotificationService as Notifications } from './notifications';

// Models (types, enums, response shapes)
export * from '../../models/notification';
Loading
Loading