@contractspec/integration.providers-impls 2.10.0 → 3.0.0

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 (57) hide show
  1. package/README.md +7 -1
  2. package/dist/impls/async-event-queue.d.ts +8 -0
  3. package/dist/impls/async-event-queue.js +47 -0
  4. package/dist/impls/health/base-health-provider.d.ts +64 -13
  5. package/dist/impls/health/base-health-provider.js +506 -156
  6. package/dist/impls/health/hybrid-health-providers.d.ts +34 -0
  7. package/dist/impls/health/hybrid-health-providers.js +1088 -0
  8. package/dist/impls/health/official-health-providers.d.ts +78 -0
  9. package/dist/impls/health/official-health-providers.js +968 -0
  10. package/dist/impls/health/provider-normalizers.d.ts +28 -0
  11. package/dist/impls/health/provider-normalizers.js +287 -0
  12. package/dist/impls/health/providers.d.ts +2 -39
  13. package/dist/impls/health/providers.js +895 -184
  14. package/dist/impls/health-provider-factory.js +1009 -196
  15. package/dist/impls/index.d.ts +6 -0
  16. package/dist/impls/index.js +1950 -278
  17. package/dist/impls/messaging-github.d.ts +17 -0
  18. package/dist/impls/messaging-github.js +110 -0
  19. package/dist/impls/messaging-slack.d.ts +14 -0
  20. package/dist/impls/messaging-slack.js +80 -0
  21. package/dist/impls/messaging-whatsapp-meta.d.ts +13 -0
  22. package/dist/impls/messaging-whatsapp-meta.js +52 -0
  23. package/dist/impls/messaging-whatsapp-twilio.d.ts +13 -0
  24. package/dist/impls/messaging-whatsapp-twilio.js +82 -0
  25. package/dist/impls/mistral-conversational.d.ts +23 -0
  26. package/dist/impls/mistral-conversational.js +476 -0
  27. package/dist/impls/mistral-conversational.session.d.ts +32 -0
  28. package/dist/impls/mistral-conversational.session.js +206 -0
  29. package/dist/impls/mistral-stt.d.ts +17 -0
  30. package/dist/impls/mistral-stt.js +167 -0
  31. package/dist/impls/provider-factory.d.ts +5 -1
  32. package/dist/impls/provider-factory.js +1943 -277
  33. package/dist/impls/stripe-payments.js +1 -1
  34. package/dist/index.d.ts +1 -0
  35. package/dist/index.js +1953 -278
  36. package/dist/messaging.d.ts +1 -0
  37. package/dist/messaging.js +3 -0
  38. package/dist/node/impls/async-event-queue.js +46 -0
  39. package/dist/node/impls/health/base-health-provider.js +506 -156
  40. package/dist/node/impls/health/hybrid-health-providers.js +1087 -0
  41. package/dist/node/impls/health/official-health-providers.js +967 -0
  42. package/dist/node/impls/health/provider-normalizers.js +286 -0
  43. package/dist/node/impls/health/providers.js +895 -184
  44. package/dist/node/impls/health-provider-factory.js +1009 -196
  45. package/dist/node/impls/index.js +1950 -278
  46. package/dist/node/impls/messaging-github.js +109 -0
  47. package/dist/node/impls/messaging-slack.js +79 -0
  48. package/dist/node/impls/messaging-whatsapp-meta.js +51 -0
  49. package/dist/node/impls/messaging-whatsapp-twilio.js +81 -0
  50. package/dist/node/impls/mistral-conversational.js +475 -0
  51. package/dist/node/impls/mistral-conversational.session.js +205 -0
  52. package/dist/node/impls/mistral-stt.js +166 -0
  53. package/dist/node/impls/provider-factory.js +1943 -277
  54. package/dist/node/impls/stripe-payments.js +1 -1
  55. package/dist/node/index.js +1953 -278
  56. package/dist/node/messaging.js +2 -0
  57. package/package.json +156 -12
@@ -0,0 +1,109 @@
1
+ // src/impls/messaging-github.ts
2
+ class GithubMessagingProvider {
3
+ token;
4
+ defaultOwner;
5
+ defaultRepo;
6
+ apiBaseUrl;
7
+ constructor(options) {
8
+ this.token = options.token;
9
+ this.defaultOwner = options.defaultOwner;
10
+ this.defaultRepo = options.defaultRepo;
11
+ this.apiBaseUrl = options.apiBaseUrl ?? "https://api.github.com";
12
+ }
13
+ async sendMessage(input) {
14
+ const target = this.resolveTarget(input);
15
+ const response = await fetch(`${this.apiBaseUrl}/repos/${target.owner}/${target.repo}/issues/${target.issueNumber}/comments`, {
16
+ method: "POST",
17
+ headers: {
18
+ authorization: `Bearer ${this.token}`,
19
+ accept: "application/vnd.github+json",
20
+ "content-type": "application/json"
21
+ },
22
+ body: JSON.stringify({ body: input.text })
23
+ });
24
+ const body = await response.json();
25
+ if (!response.ok || !body.id) {
26
+ throw new Error(`GitHub sendMessage failed: ${body.message ?? `HTTP_${response.status}`}`);
27
+ }
28
+ return {
29
+ id: String(body.id),
30
+ providerMessageId: body.node_id,
31
+ status: "sent",
32
+ sentAt: new Date,
33
+ metadata: {
34
+ url: body.html_url ?? "",
35
+ owner: target.owner,
36
+ repo: target.repo,
37
+ issueNumber: String(target.issueNumber)
38
+ }
39
+ };
40
+ }
41
+ async updateMessage(messageId, input) {
42
+ const owner = input.metadata?.owner ?? this.defaultOwner;
43
+ const repo = input.metadata?.repo ?? this.defaultRepo;
44
+ if (!owner || !repo) {
45
+ throw new Error("GitHub updateMessage requires owner and repo metadata.");
46
+ }
47
+ const response = await fetch(`${this.apiBaseUrl}/repos/${owner}/${repo}/issues/comments/${messageId}`, {
48
+ method: "PATCH",
49
+ headers: {
50
+ authorization: `Bearer ${this.token}`,
51
+ accept: "application/vnd.github+json",
52
+ "content-type": "application/json"
53
+ },
54
+ body: JSON.stringify({ body: input.text })
55
+ });
56
+ const body = await response.json();
57
+ if (!response.ok || !body.id) {
58
+ throw new Error(`GitHub updateMessage failed: ${body.message ?? `HTTP_${response.status}`}`);
59
+ }
60
+ return {
61
+ id: String(body.id),
62
+ providerMessageId: body.node_id,
63
+ status: "sent",
64
+ sentAt: new Date,
65
+ metadata: {
66
+ url: body.html_url ?? "",
67
+ owner,
68
+ repo
69
+ }
70
+ };
71
+ }
72
+ resolveTarget(input) {
73
+ const parsedRecipient = parseRecipient(input.recipientId);
74
+ const owner = parsedRecipient?.owner ?? this.defaultOwner;
75
+ const repo = parsedRecipient?.repo ?? this.defaultRepo;
76
+ const issueNumber = parsedRecipient?.issueNumber ?? parseIssueNumber(input.threadId);
77
+ if (!owner || !repo || issueNumber == null) {
78
+ throw new Error("GitHub sendMessage requires owner/repo and issueNumber (use recipientId like owner/repo#123 or provide defaults + threadId).");
79
+ }
80
+ return {
81
+ owner,
82
+ repo,
83
+ issueNumber
84
+ };
85
+ }
86
+ }
87
+ function parseRecipient(value) {
88
+ if (!value)
89
+ return null;
90
+ const match = value.trim().match(/^([^/]+)\/([^#]+)#(\d+)$/);
91
+ if (!match)
92
+ return null;
93
+ const owner = match[1];
94
+ const repo = match[2];
95
+ const issueNumber = Number(match[3]);
96
+ if (!owner || !repo || !Number.isInteger(issueNumber)) {
97
+ return null;
98
+ }
99
+ return { owner, repo, issueNumber };
100
+ }
101
+ function parseIssueNumber(value) {
102
+ if (!value)
103
+ return null;
104
+ const numeric = Number(value);
105
+ return Number.isInteger(numeric) ? numeric : null;
106
+ }
107
+ export {
108
+ GithubMessagingProvider
109
+ };
@@ -0,0 +1,79 @@
1
+ // src/impls/messaging-slack.ts
2
+ class SlackMessagingProvider {
3
+ botToken;
4
+ defaultChannelId;
5
+ apiBaseUrl;
6
+ constructor(options) {
7
+ this.botToken = options.botToken;
8
+ this.defaultChannelId = options.defaultChannelId;
9
+ this.apiBaseUrl = options.apiBaseUrl ?? "https://slack.com/api";
10
+ }
11
+ async sendMessage(input) {
12
+ const channel = input.channelId ?? input.recipientId ?? this.defaultChannelId;
13
+ if (!channel) {
14
+ throw new Error("Slack sendMessage requires channelId, recipientId, or defaultChannelId.");
15
+ }
16
+ const payload = {
17
+ channel,
18
+ text: input.text,
19
+ mrkdwn: input.markdown ?? true,
20
+ thread_ts: input.threadId
21
+ };
22
+ const response = await fetch(`${this.apiBaseUrl}/chat.postMessage`, {
23
+ method: "POST",
24
+ headers: {
25
+ authorization: `Bearer ${this.botToken}`,
26
+ "content-type": "application/json"
27
+ },
28
+ body: JSON.stringify(payload)
29
+ });
30
+ const body = await response.json();
31
+ if (!response.ok || !body.ok || !body.ts) {
32
+ throw new Error(`Slack sendMessage failed: ${body.error ?? `HTTP_${response.status}`}`);
33
+ }
34
+ return {
35
+ id: `slack:${body.channel ?? channel}:${body.ts}`,
36
+ providerMessageId: body.ts,
37
+ status: "sent",
38
+ sentAt: new Date,
39
+ metadata: {
40
+ channelId: body.channel ?? channel
41
+ }
42
+ };
43
+ }
44
+ async updateMessage(messageId, input) {
45
+ const channel = input.channelId ?? this.defaultChannelId;
46
+ if (!channel) {
47
+ throw new Error("Slack updateMessage requires channelId or defaultChannelId.");
48
+ }
49
+ const response = await fetch(`${this.apiBaseUrl}/chat.update`, {
50
+ method: "POST",
51
+ headers: {
52
+ authorization: `Bearer ${this.botToken}`,
53
+ "content-type": "application/json"
54
+ },
55
+ body: JSON.stringify({
56
+ channel,
57
+ ts: messageId,
58
+ text: input.text,
59
+ mrkdwn: input.markdown ?? true
60
+ })
61
+ });
62
+ const body = await response.json();
63
+ if (!response.ok || !body.ok || !body.ts) {
64
+ throw new Error(`Slack updateMessage failed: ${body.error ?? `HTTP_${response.status}`}`);
65
+ }
66
+ return {
67
+ id: `slack:${body.channel ?? channel}:${body.ts}`,
68
+ providerMessageId: body.ts,
69
+ status: "sent",
70
+ sentAt: new Date,
71
+ metadata: {
72
+ channelId: body.channel ?? channel
73
+ }
74
+ };
75
+ }
76
+ }
77
+ export {
78
+ SlackMessagingProvider
79
+ };
@@ -0,0 +1,51 @@
1
+ // src/impls/messaging-whatsapp-meta.ts
2
+ class MetaWhatsappMessagingProvider {
3
+ accessToken;
4
+ phoneNumberId;
5
+ apiVersion;
6
+ constructor(options) {
7
+ this.accessToken = options.accessToken;
8
+ this.phoneNumberId = options.phoneNumberId;
9
+ this.apiVersion = options.apiVersion ?? "v22.0";
10
+ }
11
+ async sendMessage(input) {
12
+ const to = input.recipientId;
13
+ if (!to) {
14
+ throw new Error("Meta WhatsApp sendMessage requires recipientId.");
15
+ }
16
+ const response = await fetch(`https://graph.facebook.com/${this.apiVersion}/${this.phoneNumberId}/messages`, {
17
+ method: "POST",
18
+ headers: {
19
+ authorization: `Bearer ${this.accessToken}`,
20
+ "content-type": "application/json"
21
+ },
22
+ body: JSON.stringify({
23
+ messaging_product: "whatsapp",
24
+ to,
25
+ type: "text",
26
+ text: {
27
+ body: input.text,
28
+ preview_url: false
29
+ }
30
+ })
31
+ });
32
+ const body = await response.json();
33
+ const messageId = body.messages?.[0]?.id;
34
+ if (!response.ok || !messageId) {
35
+ const errorCode = body.error?.code != null ? String(body.error.code) : "";
36
+ throw new Error(`Meta WhatsApp sendMessage failed: ${body.error?.message ?? `HTTP_${response.status}`}${errorCode ? ` (${errorCode})` : ""}`);
37
+ }
38
+ return {
39
+ id: messageId,
40
+ providerMessageId: messageId,
41
+ status: "sent",
42
+ sentAt: new Date,
43
+ metadata: {
44
+ phoneNumberId: this.phoneNumberId
45
+ }
46
+ };
47
+ }
48
+ }
49
+ export {
50
+ MetaWhatsappMessagingProvider
51
+ };
@@ -0,0 +1,81 @@
1
+ // src/impls/messaging-whatsapp-twilio.ts
2
+ import { Buffer } from "node:buffer";
3
+
4
+ class TwilioWhatsappMessagingProvider {
5
+ accountSid;
6
+ authToken;
7
+ fromNumber;
8
+ constructor(options) {
9
+ this.accountSid = options.accountSid;
10
+ this.authToken = options.authToken;
11
+ this.fromNumber = options.fromNumber;
12
+ }
13
+ async sendMessage(input) {
14
+ const to = normalizeWhatsappAddress(input.recipientId);
15
+ const from = normalizeWhatsappAddress(input.channelId ?? this.fromNumber);
16
+ if (!to) {
17
+ throw new Error("Twilio WhatsApp sendMessage requires recipientId.");
18
+ }
19
+ if (!from) {
20
+ throw new Error("Twilio WhatsApp sendMessage requires channelId or configured fromNumber.");
21
+ }
22
+ const params = new URLSearchParams;
23
+ params.set("To", to);
24
+ params.set("From", from);
25
+ params.set("Body", input.text);
26
+ const auth = Buffer.from(`${this.accountSid}:${this.authToken}`).toString("base64");
27
+ const response = await fetch(`https://api.twilio.com/2010-04-01/Accounts/${this.accountSid}/Messages.json`, {
28
+ method: "POST",
29
+ headers: {
30
+ authorization: `Basic ${auth}`,
31
+ "content-type": "application/x-www-form-urlencoded"
32
+ },
33
+ body: params.toString()
34
+ });
35
+ const body = await response.json();
36
+ if (!response.ok || !body.sid) {
37
+ throw new Error(`Twilio WhatsApp sendMessage failed: ${body.error_message ?? `HTTP_${response.status}`}`);
38
+ }
39
+ return {
40
+ id: body.sid,
41
+ providerMessageId: body.sid,
42
+ status: mapTwilioStatus(body.status),
43
+ sentAt: new Date,
44
+ errorCode: body.error_code != null ? String(body.error_code) : undefined,
45
+ errorMessage: body.error_message ?? undefined,
46
+ metadata: {
47
+ from,
48
+ to
49
+ }
50
+ };
51
+ }
52
+ }
53
+ function normalizeWhatsappAddress(value) {
54
+ if (!value)
55
+ return null;
56
+ if (value.startsWith("whatsapp:"))
57
+ return value;
58
+ return `whatsapp:${value}`;
59
+ }
60
+ function mapTwilioStatus(status) {
61
+ switch (status) {
62
+ case "queued":
63
+ case "accepted":
64
+ case "scheduled":
65
+ return "queued";
66
+ case "sending":
67
+ return "sending";
68
+ case "delivered":
69
+ return "delivered";
70
+ case "failed":
71
+ case "undelivered":
72
+ case "canceled":
73
+ return "failed";
74
+ case "sent":
75
+ default:
76
+ return "sent";
77
+ }
78
+ }
79
+ export {
80
+ TwilioWhatsappMessagingProvider
81
+ };