Skip to content

Commit 8a4a2a0

Browse files
sarthak688claudeclaude[bot]
committed
feat(notifications): add Notifications service foundation + getAll [internal]
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-Authored-By: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
1 parent ffb2639 commit 8a4a2a0

20 files changed

Lines changed: 883 additions & 0 deletions

File tree

package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,16 @@
215215
"types": "./dist/governance/index.d.ts",
216216
"default": "./dist/governance/index.cjs"
217217
}
218+
},
219+
"./notifications": {
220+
"import": {
221+
"types": "./dist/notifications/index.d.ts",
222+
"default": "./dist/notifications/index.mjs"
223+
},
224+
"require": {
225+
"types": "./dist/notifications/index.d.ts",
226+
"default": "./dist/notifications/index.cjs"
227+
}
218228
}
219229
},
220230
"files": [

rollup.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ const serviceEntries = [
228228
name: 'governance',
229229
input: 'src/services/governance/index.ts',
230230
output: 'governance/index'
231+
},
232+
{
233+
name: 'notifications',
234+
input: 'src/services/notification/index.ts',
235+
output: 'notifications/index'
231236
}
232237
];
233238

src/models/notification/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* Notification models barrel export.
3+
*/
4+
5+
export * from './notifications.types';
6+
export * from './notifications.models';
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* Notification field mappings (API field name → SDK field name).
3+
*
4+
* Semantic renames only — case conversion is handled by `pascalToCamelCaseKeys()`
5+
* (not needed here, the API already returns camelCase).
6+
*/
7+
export const NotificationMap: { [key: string]: string } = {
8+
isRead: 'hasRead',
9+
};
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Internal-only types for the Notification service.
3+
*
4+
* NOT exported from the public barrel (`src/models/notification/index.ts`).
5+
*/
6+
7+
import type { NotificationPriority, NotificationCategory } from './notifications.types';
8+
9+
/**
10+
* Raw notification entry shape as returned by `/odata/v1/NotificationEntry`.
11+
*
12+
* Mirrors the API contract exactly: it uses the API's `isRead` field (renamed to
13+
* `hasRead` in the SDK response) and includes the internal/transport-layer fields
14+
* the SDK drops before returning to consumers.
15+
*/
16+
export interface RawNotificationEntry {
17+
id: string;
18+
message: string | null;
19+
/** API read flag — renamed to `hasRead` in the SDK response. */
20+
isRead: boolean;
21+
publisherName: string;
22+
publisherId: string;
23+
topicName: string;
24+
topicKeyName: string;
25+
topicId: string;
26+
userId: string;
27+
userEmail: string | null;
28+
tenantId: string | null;
29+
priority: NotificationPriority;
30+
category: NotificationCategory;
31+
messageParam: string | null;
32+
redirectionUrl: string | null;
33+
publishedOn: number;
34+
// Internal/transport-layer fields the SDK strips before returning to consumers:
35+
entityOrgName?: string | null;
36+
entityTenantName?: string | null;
37+
serviceRegistryName?: string | null;
38+
messageTemplateKey?: string | null;
39+
messageVersion?: number;
40+
publicationId?: string;
41+
correlationId?: string | null;
42+
partitionKey?: string;
43+
}
44+
45+
/**
46+
* Fields stripped from each {@link RawNotificationEntry} before it is returned to the
47+
* SDK consumer as a {@link NotificationGetResponse}.
48+
*/
49+
export const INTERNAL_NOTIFICATION_FIELDS = [
50+
'entityOrgName',
51+
'entityTenantName',
52+
'serviceRegistryName',
53+
'messageTemplateKey',
54+
'messageVersion',
55+
'publicationId',
56+
'correlationId',
57+
'partitionKey',
58+
] as const satisfies ReadonlyArray<keyof RawNotificationEntry>;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* Notification service model — public response shapes and the ServiceModel interface
3+
* that drives generated API documentation.
4+
*/
5+
6+
import type {
7+
HasPaginationOptions,
8+
NonPaginatedResponse,
9+
PaginatedResponse,
10+
} from '../../utils/pagination/types';
11+
12+
import type {
13+
NotificationGetAllOptions,
14+
NotificationGetResponse,
15+
} from './notifications.types';
16+
17+
/**
18+
* Public surface of the Notifications service. JSDoc on this interface drives
19+
* the generated API reference documentation.
20+
*
21+
* Every method takes the tenant GUID as the first argument — the notification
22+
* API identifies the acting tenant via the `X-UIPATH-Internal-TenantId` header
23+
* and the SDK forwards `tenantId` into that header on each call.
24+
*/
25+
export interface NotificationServiceModel {
26+
/**
27+
* Lists notifications from the current user's inbox.
28+
*
29+
* Returns the full list when no pagination params are provided, or a paginated cursor result
30+
* when any of `pageSize`/`cursor`/`jumpToPage` is supplied. Supports OData `filter` and
31+
* `orderby` query options.
32+
*
33+
* @param tenantId - Tenant GUID (sent via `X-UIPATH-Internal-TenantId`)
34+
* @param options - Optional OData query and pagination options
35+
* @returns Promise resolving to either a {@link NonPaginatedResponse}<{@link NotificationGetResponse}> or a {@link PaginatedResponse}<{@link NotificationGetResponse}> when pagination options are used.
36+
*
37+
* @example Basic usage
38+
* ```typescript
39+
* import { Notifications } from '@uipath/uipath-typescript/notifications';
40+
*
41+
* const notifications = new Notifications(sdk);
42+
* const all = await notifications.getAll('<tenantId>');
43+
* ```
44+
*
45+
* @example Filter unread, most recent first
46+
* ```typescript
47+
* const unread = await notifications.getAll('<tenantId>', {
48+
* filter: 'hasRead eq false',
49+
* orderby: 'publishedOn desc',
50+
* });
51+
* ```
52+
*
53+
* @example First page with pagination
54+
* ```typescript
55+
* const page1 = await notifications.getAll('<tenantId>', { pageSize: 20 });
56+
* if (page1.hasNextPage) {
57+
* const page2 = await notifications.getAll('<tenantId>', { cursor: page1.nextCursor });
58+
* }
59+
* ```
60+
* @internal
61+
*/
62+
getAll<T extends NotificationGetAllOptions = NotificationGetAllOptions>(
63+
tenantId: string,
64+
options?: T
65+
): Promise<
66+
T extends HasPaginationOptions<T>
67+
? PaginatedResponse<NotificationGetResponse>
68+
: NonPaginatedResponse<NotificationGetResponse>
69+
>;
70+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* Notification inbox types — raw API shapes and request/response options.
3+
*/
4+
5+
import type { PaginationOptions } from '../../utils/pagination/types';
6+
7+
/**
8+
* Priority level assigned to a notification by the publisher.
9+
*/
10+
export enum NotificationPriority {
11+
Low = 'Low',
12+
Medium = 'Medium',
13+
High = 'High',
14+
Critical = 'Critical',
15+
}
16+
17+
/**
18+
* Severity classification of a notification topic.
19+
*/
20+
export enum NotificationCategory {
21+
/** Informational — no action required. */
22+
Info = 'Info',
23+
/** Successful operation completed. */
24+
Success = 'Success',
25+
/** Warning — degraded behaviour or non-fatal issue. */
26+
Warn = 'Warn',
27+
/** Error — operation failed but the system continues. */
28+
Error = 'Error',
29+
/** Fatal — unrecoverable failure. */
30+
Fatal = 'Fatal',
31+
}
32+
33+
/**
34+
* Notification entry as returned by `GET /odata/v1/NotificationEntry`.
35+
*
36+
* Field selection: many internal/transport-layer fields (`partitionKey`, `correlationId`,
37+
* `publicationId`, `messageVersion`, `messageTemplateKey`, `serviceRegistryName`,
38+
* `entityOrgName`, `entityTenantName`) are returned by the API but dropped from the SDK
39+
* because they have no use for an application developer.
40+
*/
41+
export interface NotificationGetResponse {
42+
/** Notification GUID. */
43+
id: string;
44+
/** Resolved notification message text. */
45+
message: string | null;
46+
/** Whether the user has read this notification. */
47+
hasRead: boolean;
48+
/** Name of the publisher (e.g. `Orchestrator`, `Actions`). */
49+
publisherName: string;
50+
/** Publisher GUID. */
51+
publisherId: string;
52+
/** Human-readable topic name. */
53+
topicName: string;
54+
/** Stable topic identifier (e.g. `Process.JobExecution.Faulted`). */
55+
topicKeyName: string;
56+
/** Topic GUID. */
57+
topicId: string;
58+
/** GUID of the user this notification belongs to (returned uppercase by the API). */
59+
userId: string;
60+
/** Email of the user. Often `null`. */
61+
userEmail: string | null;
62+
/** Tenant GUID this notification belongs to. Often `null` for org-scoped notifications. */
63+
tenantId: string | null;
64+
/** Notification priority. */
65+
priority: NotificationPriority;
66+
/** Notification severity category. */
67+
category: NotificationCategory;
68+
/** JSON string of template parameters — parse with `JSON.parse()`. May be `null`. */
69+
messageParam: string | null;
70+
/** URL to navigate to when the notification is clicked. */
71+
redirectionUrl: string | null;
72+
/** Unix epoch **seconds** when the notification was published. */
73+
publishedOn: number;
74+
}
75+
76+
/**
77+
* Options for `Notifications.getAll()`.
78+
*
79+
* Supports OData query options (`filter`, `orderby`) and SDK cursor pagination.
80+
*
81+
* Notes:
82+
* - `$select` and `$expand` are not exposed because the API returns 500 on `$select`
83+
* and there are no expandable relationships on this endpoint.
84+
*/
85+
export type NotificationGetAllOptions = PaginationOptions & {
86+
filter?: string;
87+
orderby?: string;
88+
};

src/services/notification/index.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Notification Service Module
3+
*
4+
* Provides access to the UiPath Notification platform from the perspective of an
5+
* authenticated user (UserContext):
6+
* - `Notifications` — list operations on the user's inbox (further operations land in
7+
* follow-up PRs)
8+
*
9+
* Publishing (sending) notifications is a first-party service action and is NOT part of this module.
10+
*
11+
* @example
12+
* ```typescript
13+
* import { UiPath } from '@uipath/uipath-typescript/core';
14+
* import { Notifications } from '@uipath/uipath-typescript/notifications';
15+
*
16+
* const sdk = new UiPath(config);
17+
* await sdk.initialize();
18+
*
19+
* const notifications = new Notifications(sdk);
20+
* const unread = await notifications.getAll('<tenantId>', { filter: 'hasRead eq false' });
21+
* ```
22+
*
23+
* @module
24+
*/
25+
26+
export { NotificationService as Notifications } from './notifications';
27+
28+
// Models (types, enums, response shapes)
29+
export * from '../../models/notification';

0 commit comments

Comments
 (0)