@marktoflow/integrations 2.0.4-alpha.1 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +2 -2
  2. package/dist/adapters/claude-code.d.ts +34 -0
  3. package/dist/adapters/claude-code.d.ts.map +1 -0
  4. package/dist/adapters/claude-code.js +89 -0
  5. package/dist/adapters/claude-code.js.map +1 -0
  6. package/dist/adapters/github-copilot-types.d.ts +2 -2
  7. package/dist/adapters/github-copilot-workflow.d.ts +2 -2
  8. package/dist/index.d.ts +0 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +1 -4
  11. package/dist/index.js.map +1 -1
  12. package/dist/reliability/index.d.ts +1 -3
  13. package/dist/reliability/index.d.ts.map +1 -1
  14. package/dist/reliability/index.js +1 -3
  15. package/dist/reliability/index.js.map +1 -1
  16. package/dist/reliability/wrapper.d.ts +0 -9
  17. package/dist/reliability/wrapper.d.ts.map +1 -1
  18. package/dist/reliability/wrapper.js +12 -62
  19. package/dist/reliability/wrapper.js.map +1 -1
  20. package/dist/services/base-client.d.ts.map +1 -1
  21. package/dist/services/base-client.js +3 -25
  22. package/dist/services/base-client.js.map +1 -1
  23. package/dist/services/discord.d.ts.map +1 -1
  24. package/dist/services/discord.js +0 -6
  25. package/dist/services/discord.js.map +1 -1
  26. package/dist/services/gmail.d.ts.map +1 -1
  27. package/dist/services/gmail.js +47 -65
  28. package/dist/services/gmail.js.map +1 -1
  29. package/dist/services/google-calendar.js +5 -9
  30. package/dist/services/google-calendar.js.map +1 -1
  31. package/dist/services/google-docs.js +5 -9
  32. package/dist/services/google-docs.js.map +1 -1
  33. package/dist/services/google-drive.js +5 -9
  34. package/dist/services/google-drive.js.map +1 -1
  35. package/dist/services/google-sheets.js +5 -9
  36. package/dist/services/google-sheets.js.map +1 -1
  37. package/dist/services/http.d.ts.map +1 -1
  38. package/dist/services/http.js +1 -15
  39. package/dist/services/http.js.map +1 -1
  40. package/dist/services/mailchimp.d.ts.map +1 -1
  41. package/dist/services/mailchimp.js +0 -3
  42. package/dist/services/mailchimp.js.map +1 -1
  43. package/dist/services/outlook.d.ts.map +1 -1
  44. package/dist/services/outlook.js +11 -14
  45. package/dist/services/outlook.js.map +1 -1
  46. package/dist/services/shopify.d.ts.map +1 -1
  47. package/dist/services/shopify.js +0 -3
  48. package/dist/services/shopify.js.map +1 -1
  49. package/dist/services/trello.d.ts.map +1 -1
  50. package/dist/services/trello.js +1 -7
  51. package/dist/services/trello.js.map +1 -1
  52. package/package.json +3 -6
  53. package/dist/adapters/claude-agent-hooks.d.ts +0 -176
  54. package/dist/reliability/circuit-breaker.d.ts +0 -67
  55. package/dist/reliability/circuit-breaker.d.ts.map +0 -1
  56. package/dist/reliability/circuit-breaker.js +0 -164
  57. package/dist/reliability/circuit-breaker.js.map +0 -1
  58. package/dist/reliability/rate-limiter.d.ts +0 -62
  59. package/dist/reliability/rate-limiter.d.ts.map +0 -1
  60. package/dist/reliability/rate-limiter.js +0 -194
  61. package/dist/reliability/rate-limiter.js.map +0 -1
  62. package/dist/services/github.d.ts +0 -3
  63. package/dist/services/gmail-trigger.d.ts +0 -92
  64. package/dist/services/gmail.d.ts +0 -116
  65. package/dist/services/google-calendar.d.ts +0 -220
  66. package/dist/services/google-docs.d.ts +0 -197
  67. package/dist/services/google-drive.d.ts +0 -149
  68. package/dist/services/google-sheets.d.ts +0 -165
  69. package/dist/services/http.d.ts +0 -120
  70. package/dist/services/jira.d.ts +0 -3
  71. package/dist/services/linear.d.ts +0 -163
  72. package/dist/services/mysql.d.ts +0 -91
  73. package/dist/services/outlook-trigger.d.ts +0 -121
  74. package/dist/services/outlook.d.ts +0 -237
  75. package/dist/services/postgres.d.ts +0 -83
  76. package/dist/services/rss.d.ts +0 -57
  77. package/dist/services/rss.d.ts.map +0 -1
  78. package/dist/services/rss.js +0 -190
  79. package/dist/services/rss.js.map +0 -1
  80. package/dist/services/slack-socket.d.ts +0 -18
  81. package/dist/services/slack.d.ts +0 -3
  82. package/dist/services/whatsapp.d.ts +0 -311
@@ -1,121 +0,0 @@
1
- import { TriggerType } from '@marktoflow/core';
2
- export interface OutlookTriggerConfig {
3
- token: string;
4
- notificationUrl: string;
5
- changeTypes?: ('created' | 'updated' | 'deleted')[];
6
- resource?: string;
7
- expirationMinutes?: number;
8
- clientState?: string;
9
- triggers: Array<{
10
- id: string;
11
- event: 'email_received' | 'email_updated' | 'email_deleted';
12
- handler: (payload: OutlookTriggerPayload) => Promise<void>;
13
- }>;
14
- }
15
- export interface OutlookTriggerPayload {
16
- type: TriggerType;
17
- event: 'email_received' | 'email_updated' | 'email_deleted';
18
- subscriptionId: string;
19
- changeType: string;
20
- resource: string;
21
- resourceData?: {
22
- id: string;
23
- [key: string]: unknown;
24
- };
25
- clientState?: string;
26
- tenantId?: string;
27
- }
28
- export interface GraphSubscription {
29
- id: string;
30
- resource: string;
31
- changeType: string;
32
- notificationUrl: string;
33
- expirationDateTime: string;
34
- clientState?: string;
35
- }
36
- export interface GraphNotification {
37
- value: Array<{
38
- subscriptionId: string;
39
- subscriptionExpirationDateTime: string;
40
- changeType: string;
41
- resource: string;
42
- resourceData?: {
43
- '@odata.type': string;
44
- '@odata.id': string;
45
- '@odata.etag': string;
46
- id: string;
47
- [key: string]: unknown;
48
- };
49
- clientState?: string;
50
- tenantId?: string;
51
- }>;
52
- }
53
- export interface GraphValidationRequest extends Record<string, unknown> {
54
- validationToken: string;
55
- }
56
- /**
57
- * Outlook trigger handler for Microsoft Graph webhook subscriptions.
58
- *
59
- * Setup requirements:
60
- * 1. Register an Azure AD application with Mail.Read permissions
61
- * 2. Set up a publicly accessible webhook endpoint
62
- * 3. Call subscribe() to start receiving notifications
63
- * 4. Handle subscription renewal before expiration (max ~3 days)
64
- */
65
- export declare class OutlookTrigger {
66
- private config;
67
- private client;
68
- private subscription?;
69
- constructor(config: OutlookTriggerConfig);
70
- /**
71
- * Create a subscription to receive mail notifications.
72
- */
73
- subscribe(): Promise<GraphSubscription>;
74
- /**
75
- * Renew an existing subscription.
76
- */
77
- renew(expirationMinutes?: number): Promise<GraphSubscription>;
78
- /**
79
- * Delete the subscription (stop receiving notifications).
80
- */
81
- unsubscribe(): Promise<void>;
82
- /**
83
- * Get the current subscription status.
84
- */
85
- getSubscription(): GraphSubscription | undefined;
86
- /**
87
- * Check if subscription is still active (not expired).
88
- */
89
- isSubscriptionActive(): boolean;
90
- /**
91
- * Handle an incoming Graph notification.
92
- * Call this from your webhook endpoint after validation.
93
- */
94
- handleNotification(notification: GraphNotification): Promise<void>;
95
- /**
96
- * Check if a request is a validation request from Graph.
97
- */
98
- static isValidationRequest(query: Record<string, unknown>): query is GraphValidationRequest;
99
- /**
100
- * Validate the notification body structure.
101
- */
102
- static validateNotification(body: unknown): body is GraphNotification;
103
- }
104
- /**
105
- * Express/Fastify-compatible middleware for handling Outlook Graph webhooks.
106
- *
107
- * Handles both:
108
- * - Subscription validation (GET with validationToken)
109
- * - Notification processing (POST with notification payload)
110
- */
111
- export declare function createOutlookWebhookHandler(trigger: OutlookTrigger): (req: {
112
- method: string;
113
- query: Record<string, unknown>;
114
- body: unknown;
115
- }, res: {
116
- status: (code: number) => {
117
- send: (body?: string) => void;
118
- };
119
- contentType: (type: string) => void;
120
- }) => Promise<void>;
121
- //# sourceMappingURL=outlook-trigger.d.ts.map
@@ -1,237 +0,0 @@
1
- import { Client } from '@microsoft/microsoft-graph-client';
2
- import { SDKInitializer } from '@marktoflow/core';
3
- export interface OutlookEmail {
4
- id: string;
5
- conversationId: string;
6
- subject: string;
7
- from: string;
8
- fromAddress: string;
9
- to: {
10
- name: string;
11
- address: string;
12
- }[];
13
- cc?: {
14
- name: string;
15
- address: string;
16
- }[];
17
- bcc?: {
18
- name: string;
19
- address: string;
20
- }[];
21
- receivedDateTime: string;
22
- sentDateTime?: string;
23
- bodyPreview: string;
24
- body?: string;
25
- bodyHtml?: string;
26
- isRead: boolean;
27
- hasAttachments: boolean;
28
- importance: 'low' | 'normal' | 'high';
29
- categories: string[];
30
- webLink?: string;
31
- }
32
- export interface GetEmailsOptions {
33
- folder?: string;
34
- filter?: string;
35
- select?: string[];
36
- top?: number;
37
- skip?: number;
38
- orderBy?: string;
39
- search?: string;
40
- }
41
- export interface SendEmailOptions {
42
- to: string | string[] | {
43
- name?: string;
44
- address: string;
45
- }[];
46
- subject: string;
47
- body: string;
48
- bodyType?: 'text' | 'html';
49
- cc?: string | string[] | {
50
- name?: string;
51
- address: string;
52
- }[];
53
- bcc?: string | string[] | {
54
- name?: string;
55
- address: string;
56
- }[];
57
- importance?: 'low' | 'normal' | 'high';
58
- saveToSentItems?: boolean;
59
- replyTo?: string | {
60
- name?: string;
61
- address: string;
62
- }[];
63
- }
64
- export interface CreateDraftOptions {
65
- to?: string | string[] | {
66
- name?: string;
67
- address: string;
68
- }[];
69
- subject?: string;
70
- body?: string;
71
- bodyType?: 'text' | 'html';
72
- cc?: string | string[] | {
73
- name?: string;
74
- address: string;
75
- }[];
76
- bcc?: string | string[] | {
77
- name?: string;
78
- address: string;
79
- }[];
80
- importance?: 'low' | 'normal' | 'high';
81
- }
82
- export interface CalendarEvent {
83
- id: string;
84
- subject: string;
85
- body?: string;
86
- bodyHtml?: string;
87
- start: {
88
- dateTime: string;
89
- timeZone: string;
90
- };
91
- end: {
92
- dateTime: string;
93
- timeZone: string;
94
- };
95
- location?: string;
96
- attendees: {
97
- name: string;
98
- address: string;
99
- type: string;
100
- }[];
101
- organizer?: {
102
- name: string;
103
- address: string;
104
- };
105
- isOnlineMeeting: boolean;
106
- onlineMeetingUrl?: string;
107
- webLink?: string;
108
- }
109
- export interface GetEventsOptions {
110
- startDateTime?: string;
111
- endDateTime?: string;
112
- top?: number;
113
- skip?: number;
114
- filter?: string;
115
- orderBy?: string;
116
- }
117
- export interface CreateEventOptions {
118
- subject: string;
119
- body?: string;
120
- bodyType?: 'text' | 'html';
121
- start: {
122
- dateTime: string;
123
- timeZone?: string;
124
- };
125
- end: {
126
- dateTime: string;
127
- timeZone?: string;
128
- };
129
- location?: string;
130
- attendees?: (string | {
131
- name?: string;
132
- address: string;
133
- })[];
134
- isOnlineMeeting?: boolean;
135
- reminderMinutesBeforeStart?: number;
136
- }
137
- export interface OutlookDraft {
138
- id: string;
139
- conversationId?: string;
140
- webLink?: string;
141
- }
142
- export interface GetEmailsResult {
143
- emails: OutlookEmail[];
144
- nextLink?: string;
145
- }
146
- /**
147
- * Outlook actions for workflow integration (Email + Calendar)
148
- */
149
- export declare class OutlookActions {
150
- private client;
151
- constructor(client: Client);
152
- /**
153
- * Get emails from Outlook mailbox
154
- */
155
- getEmails(options?: GetEmailsOptions): Promise<GetEmailsResult>;
156
- /**
157
- * Get a specific email by ID
158
- */
159
- getEmail(id: string): Promise<OutlookEmail>;
160
- /**
161
- * Send an email via Outlook
162
- */
163
- sendEmail(options: SendEmailOptions): Promise<void>;
164
- /**
165
- * Create a draft email in Outlook
166
- */
167
- createDraft(options: CreateDraftOptions): Promise<OutlookDraft>;
168
- /**
169
- * Reply to an email
170
- */
171
- reply(messageId: string, body: string, bodyType?: 'text' | 'html', replyAll?: boolean): Promise<void>;
172
- /**
173
- * Forward an email
174
- */
175
- forward(messageId: string, to: string | string[] | {
176
- name?: string;
177
- address: string;
178
- }[], comment?: string): Promise<void>;
179
- /**
180
- * Mark an email as read
181
- */
182
- markAsRead(id: string): Promise<void>;
183
- /**
184
- * Mark an email as unread
185
- */
186
- markAsUnread(id: string): Promise<void>;
187
- /**
188
- * Move an email to a folder
189
- */
190
- moveToFolder(messageId: string, destinationFolderId: string): Promise<void>;
191
- /**
192
- * Delete an email (move to deleted items)
193
- */
194
- delete(id: string): Promise<void>;
195
- /**
196
- * List mail folders
197
- */
198
- listFolders(): Promise<{
199
- id: string;
200
- displayName: string;
201
- totalItemCount: number;
202
- }[]>;
203
- /**
204
- * Get calendar events
205
- */
206
- getEvents(options?: GetEventsOptions): Promise<CalendarEvent[]>;
207
- /**
208
- * Get a specific calendar event by ID
209
- */
210
- getEvent(id: string): Promise<CalendarEvent>;
211
- /**
212
- * Create a calendar event
213
- */
214
- createEvent(options: CreateEventOptions): Promise<CalendarEvent>;
215
- /**
216
- * Update a calendar event
217
- */
218
- updateEvent(id: string, updates: Partial<CreateEventOptions>): Promise<CalendarEvent>;
219
- /**
220
- * Delete a calendar event
221
- */
222
- deleteEvent(id: string): Promise<void>;
223
- /**
224
- * Accept a meeting invitation
225
- */
226
- acceptEvent(id: string, comment?: string, sendResponse?: boolean): Promise<void>;
227
- /**
228
- * Decline a meeting invitation
229
- */
230
- declineEvent(id: string, comment?: string, sendResponse?: boolean): Promise<void>;
231
- /**
232
- * Tentatively accept a meeting invitation
233
- */
234
- tentativelyAcceptEvent(id: string, comment?: string, sendResponse?: boolean): Promise<void>;
235
- }
236
- export declare const OutlookInitializer: SDKInitializer;
237
- //# sourceMappingURL=outlook.d.ts.map
@@ -1,83 +0,0 @@
1
- /**
2
- * PostgreSQL Integration
3
- *
4
- * Popular open-source relational database.
5
- * API: Using node-postgres (pg) driver
6
- */
7
- import { SDKInitializer } from '@marktoflow/core';
8
- export interface PostgresConfig {
9
- host: string;
10
- port?: number;
11
- database: string;
12
- user: string;
13
- password: string;
14
- ssl?: boolean | {
15
- rejectUnauthorized?: boolean;
16
- };
17
- connectionTimeoutMillis?: number;
18
- idleTimeoutMillis?: number;
19
- max?: number;
20
- }
21
- export interface QueryResult<T = unknown> {
22
- rows: T[];
23
- rowCount: number;
24
- command: string;
25
- fields: {
26
- name: string;
27
- dataTypeID: number;
28
- }[];
29
- }
30
- export interface PostgresTransaction {
31
- query<T = unknown>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
32
- commit(): Promise<void>;
33
- rollback(): Promise<void>;
34
- }
35
- /**
36
- * PostgreSQL client wrapper for workflow integration
37
- * Note: This is a lightweight wrapper. The actual pg module will be dynamically imported.
38
- */
39
- export declare class PostgresClient {
40
- private pool;
41
- private config;
42
- constructor(config: PostgresConfig);
43
- /**
44
- * Initialize the connection pool
45
- */
46
- connect(): Promise<void>;
47
- /**
48
- * Execute a SQL query
49
- */
50
- query<T = unknown>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
51
- /**
52
- * Select data from a table
53
- */
54
- select<T = Record<string, unknown>>(table: string, options?: {
55
- columns?: string[];
56
- where?: Record<string, unknown>;
57
- orderBy?: string;
58
- limit?: number;
59
- offset?: number;
60
- }): Promise<T[]>;
61
- /**
62
- * Insert data into a table
63
- */
64
- insert<T = Record<string, unknown>>(table: string, data: Record<string, unknown> | Record<string, unknown>[], returning?: string[]): Promise<T[]>;
65
- /**
66
- * Update data in a table
67
- */
68
- update<T = Record<string, unknown>>(table: string, data: Record<string, unknown>, where: Record<string, unknown>, returning?: string[]): Promise<T[]>;
69
- /**
70
- * Delete data from a table
71
- */
72
- delete<T = Record<string, unknown>>(table: string, where: Record<string, unknown>, returning?: string[]): Promise<T[]>;
73
- /**
74
- * Begin a transaction
75
- */
76
- transaction<T>(callback: (trx: PostgresTransaction) => Promise<T>): Promise<T>;
77
- /**
78
- * Close the connection pool
79
- */
80
- close(): Promise<void>;
81
- }
82
- export declare const PostgresInitializer: SDKInitializer;
83
- //# sourceMappingURL=postgres.d.ts.map
@@ -1,57 +0,0 @@
1
- /**
2
- * RSS/Atom Feed Integration
3
- *
4
- * Fetch and parse RSS 2.0 and Atom feeds for workflow automation.
5
- * No authentication required for public feeds; supports custom headers for private feeds.
6
- */
7
- import { SDKInitializer } from '@marktoflow/core';
8
- export interface RssFeedItem {
9
- title: string;
10
- link: string;
11
- description: string;
12
- pubDate: string;
13
- guid: string;
14
- author: string;
15
- categories: string[];
16
- }
17
- export interface RssFeed {
18
- title: string;
19
- description: string;
20
- link: string;
21
- language: string;
22
- lastBuildDate: string;
23
- items: RssFeedItem[];
24
- }
25
- export interface FetchFeedOptions {
26
- url: string;
27
- headers?: Record<string, string>;
28
- timeout?: number;
29
- }
30
- export interface GetItemsOptions extends FetchFeedOptions {
31
- /** Only return items published after this date */
32
- since?: string | Date;
33
- /** Only return items matching this regex pattern (tested against title) */
34
- filter?: string;
35
- /** Maximum number of items to return */
36
- maxItems?: number;
37
- }
38
- export declare class RssClient {
39
- private parser;
40
- private defaultHeaders;
41
- private defaultTimeout;
42
- constructor(options?: {
43
- headers?: Record<string, string>;
44
- timeout?: number;
45
- });
46
- fetch(options: FetchFeedOptions): Promise<RssFeed>;
47
- getItems(options: GetItemsOptions): Promise<RssFeedItem[]>;
48
- private normalizeFeed;
49
- private normalizeRssItem;
50
- private normalizeAtomEntry;
51
- private text;
52
- private atomLink;
53
- private atomAuthor;
54
- private toArray;
55
- }
56
- export declare const RssInitializer: SDKInitializer;
57
- //# sourceMappingURL=rss.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rss.d.ts","sourceRoot":"","sources":["../../src/services/rss.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAc,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAI9D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE;IAUtE,KAAK,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IA4BlD,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAwBhE,OAAO,CAAC,aAAa;IAgCrB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,IAAI;IAUZ,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,OAAO;CAKhB;AAID,eAAO,MAAM,cAAc,EAAE,cA4B5B,CAAC"}
@@ -1,190 +0,0 @@
1
- /**
2
- * RSS/Atom Feed Integration
3
- *
4
- * Fetch and parse RSS 2.0 and Atom feeds for workflow automation.
5
- * No authentication required for public feeds; supports custom headers for private feeds.
6
- */
7
- import { XMLParser } from 'fast-xml-parser';
8
- // ── Client ───────────────────────────────────────────────────────────────────
9
- export class RssClient {
10
- parser;
11
- defaultHeaders;
12
- defaultTimeout;
13
- constructor(options) {
14
- this.parser = new XMLParser({
15
- ignoreAttributes: false,
16
- attributeNamePrefix: '@_',
17
- textNodeName: '#text',
18
- });
19
- this.defaultHeaders = options?.headers ?? {};
20
- this.defaultTimeout = options?.timeout ?? 30_000;
21
- }
22
- async fetch(options) {
23
- const { url, headers, timeout } = options;
24
- const controller = new AbortController();
25
- const timer = setTimeout(() => controller.abort(), timeout ?? this.defaultTimeout);
26
- try {
27
- const res = await global.fetch(url, {
28
- headers: {
29
- Accept: 'application/rss+xml, application/atom+xml, application/xml, text/xml',
30
- ...this.defaultHeaders,
31
- ...headers,
32
- },
33
- signal: controller.signal,
34
- });
35
- if (!res.ok) {
36
- throw new Error(`RSS fetch failed: ${res.status} ${res.statusText}`);
37
- }
38
- const xml = await res.text();
39
- const parsed = this.parser.parse(xml);
40
- return this.normalizeFeed(parsed, url);
41
- }
42
- finally {
43
- clearTimeout(timer);
44
- }
45
- }
46
- async getItems(options) {
47
- const feed = await this.fetch(options);
48
- let items = feed.items;
49
- if (options.since) {
50
- const sinceDate = new Date(options.since);
51
- items = items.filter((item) => {
52
- if (!item.pubDate)
53
- return true;
54
- return new Date(item.pubDate) > sinceDate;
55
- });
56
- }
57
- if (options.filter) {
58
- const re = new RegExp(options.filter, 'i');
59
- items = items.filter((item) => re.test(item.title));
60
- }
61
- if (options.maxItems !== undefined) {
62
- items = items.slice(0, options.maxItems);
63
- }
64
- return items;
65
- }
66
- normalizeFeed(parsed, url) {
67
- // Atom feed
68
- if (parsed.feed) {
69
- const feed = parsed.feed;
70
- const entries = this.toArray(feed.entry);
71
- return {
72
- title: this.text(feed.title),
73
- description: this.text(feed.subtitle) || this.text(feed.title),
74
- link: this.atomLink(feed.link) || url,
75
- language: feed['@_xml:lang'] ?? '',
76
- lastBuildDate: this.text(feed.updated) || '',
77
- items: entries.map((e) => this.normalizeAtomEntry(e)),
78
- };
79
- }
80
- // RSS 2.0
81
- const channel = parsed.rss?.channel;
82
- if (!channel) {
83
- return { title: '', description: '', link: url, language: '', lastBuildDate: '', items: [] };
84
- }
85
- const rawItems = this.toArray(channel.item);
86
- return {
87
- title: this.text(channel.title),
88
- description: this.text(channel.description),
89
- link: this.text(channel.link) || url,
90
- language: channel.language ?? '',
91
- lastBuildDate: this.text(channel.lastBuildDate) || '',
92
- items: rawItems.map((item) => this.normalizeRssItem(item)),
93
- };
94
- }
95
- normalizeRssItem(item) {
96
- return {
97
- title: this.text(item.title),
98
- link: this.text(item.link),
99
- description: this.text(item.description),
100
- pubDate: this.text(item.pubDate),
101
- guid: this.text(item.guid) || this.text(item.link),
102
- author: this.text(item.author) || this.text(item['dc:creator']),
103
- categories: this.toArray(item.category).map((c) => this.text(c)),
104
- };
105
- }
106
- normalizeAtomEntry(entry) {
107
- return {
108
- title: this.text(entry.title),
109
- link: this.atomLink(entry.link) || this.text(entry.link),
110
- description: this.text(entry.summary) || this.text(entry.content),
111
- pubDate: this.text(entry.updated) || this.text(entry.published),
112
- guid: this.text(entry.id),
113
- author: this.atomAuthor(entry.author),
114
- categories: this.toArray(entry.category).map((c) => typeof c === 'object' && c !== null ? c['@_term'] ?? '' : this.text(c)),
115
- };
116
- }
117
- text(val) {
118
- if (val === undefined || val === null)
119
- return '';
120
- if (typeof val === 'string')
121
- return val;
122
- if (typeof val === 'number')
123
- return String(val);
124
- if (typeof val === 'object' && val !== null && '#text' in val) {
125
- return String(val['#text']);
126
- }
127
- return String(val);
128
- }
129
- atomLink(val) {
130
- if (!val)
131
- return '';
132
- if (typeof val === 'string')
133
- return val;
134
- if (Array.isArray(val)) {
135
- const alt = val.find((l) => l['@_rel'] === 'alternate');
136
- const link = alt ?? val[0];
137
- return link?.['@_href'] ?? '';
138
- }
139
- if (typeof val === 'object') {
140
- return val['@_href'] ?? '';
141
- }
142
- return '';
143
- }
144
- atomAuthor(val) {
145
- if (!val)
146
- return '';
147
- if (typeof val === 'string')
148
- return val;
149
- if (typeof val === 'object' && val !== null) {
150
- return this.text(val.name);
151
- }
152
- return '';
153
- }
154
- toArray(val) {
155
- if (!val)
156
- return [];
157
- if (Array.isArray(val))
158
- return val;
159
- return [val];
160
- }
161
- }
162
- // ── Initializer ──────────────────────────────────────────────────────────────
163
- export const RssInitializer = {
164
- async initialize(_module, config) {
165
- const headers = config.options?.['headers'];
166
- const timeout = config.options?.['timeout'];
167
- const client = new RssClient({ headers, timeout });
168
- return {
169
- client,
170
- fetch: async (inputs) => {
171
- return client.fetch({
172
- url: inputs.url,
173
- headers: inputs.headers,
174
- timeout: inputs.timeout,
175
- });
176
- },
177
- getItems: async (inputs) => {
178
- return client.getItems({
179
- url: inputs.url,
180
- headers: inputs.headers,
181
- timeout: inputs.timeout,
182
- since: inputs.since,
183
- filter: inputs.filter,
184
- maxItems: inputs.maxItems,
185
- });
186
- },
187
- };
188
- },
189
- };
190
- //# sourceMappingURL=rss.js.map