@pidgeon-ai/cli 1.0.1 → 1.2.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.
- package/LICENSE +21 -0
- package/dist/{chunk-VCNNUD25.js → chunk-IU5VSUXX.js} +125 -6
- package/dist/chunk-IU5VSUXX.js.map +1 -0
- package/dist/{chunk-75GJTRBD.js → chunk-K5E2QAJE.js} +99 -6
- package/dist/chunk-K5E2QAJE.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/commands.gen.js +1 -1
- package/dist/index.js +2 -2
- package/package.json +8 -4
- package/dist/chunk-75GJTRBD.js.map +0 -1
- package/dist/chunk-VCNNUD25.js.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PCN Labs OÜ
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
COMMANDS,
|
|
4
4
|
__export
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-K5E2QAJE.js";
|
|
6
6
|
|
|
7
7
|
// ../sdk/dist/index.js
|
|
8
8
|
var dist_exports = {};
|
|
@@ -49,6 +49,7 @@ __export(dist_exports, {
|
|
|
49
49
|
draftsUpdate: () => draftsUpdate,
|
|
50
50
|
eventsGet: () => eventsGet,
|
|
51
51
|
eventsList: () => eventsList,
|
|
52
|
+
eventsStream: () => eventsStream,
|
|
52
53
|
identitiesAccessCreate: () => identitiesAccessCreate,
|
|
53
54
|
identitiesAccessDelete: () => identitiesAccessDelete,
|
|
54
55
|
identitiesAccessGet: () => identitiesAccessGet,
|
|
@@ -77,6 +78,7 @@ __export(dist_exports, {
|
|
|
77
78
|
mailboxesEmptyTrash: () => mailboxesEmptyTrash,
|
|
78
79
|
mailboxesList: () => mailboxesList,
|
|
79
80
|
mailboxesListFolder: () => mailboxesListFolder,
|
|
81
|
+
meGet: () => meGet,
|
|
80
82
|
messagesAct: () => messagesAct,
|
|
81
83
|
messagesForward: () => messagesForward,
|
|
82
84
|
messagesGet: () => messagesGet,
|
|
@@ -94,6 +96,7 @@ __export(dist_exports, {
|
|
|
94
96
|
routingDelete: () => routingDelete,
|
|
95
97
|
routingList: () => routingList,
|
|
96
98
|
routingUpdate: () => routingUpdate,
|
|
99
|
+
streamEvents: () => streamEvents,
|
|
97
100
|
threadsGet: () => threadsGet,
|
|
98
101
|
threadsLabelsCreate: () => threadsLabelsCreate,
|
|
99
102
|
threadsLabelsDelete: () => threadsLabelsDelete,
|
|
@@ -155,7 +158,7 @@ function createSseClient({
|
|
|
155
158
|
...options
|
|
156
159
|
}) {
|
|
157
160
|
let lastEventId;
|
|
158
|
-
const
|
|
161
|
+
const sleep2 = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
159
162
|
const createStream = async function* () {
|
|
160
163
|
let retryDelay = sseDefaultRetryDelay ?? 3e3;
|
|
161
164
|
let attempt = 0;
|
|
@@ -259,7 +262,7 @@ function createSseClient({
|
|
|
259
262
|
break;
|
|
260
263
|
}
|
|
261
264
|
const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 3e4);
|
|
262
|
-
await
|
|
265
|
+
await sleep2(backoff);
|
|
263
266
|
}
|
|
264
267
|
}
|
|
265
268
|
};
|
|
@@ -1085,7 +1088,7 @@ var messagesSend = (options) => (options.client ?? client).post({
|
|
|
1085
1088
|
...options.headers
|
|
1086
1089
|
}
|
|
1087
1090
|
});
|
|
1088
|
-
var messagesSearch = (options) => (options
|
|
1091
|
+
var messagesSearch = (options) => (options?.client ?? client).get({
|
|
1089
1092
|
security: [{ scheme: "bearer", type: "http" }],
|
|
1090
1093
|
url: "/messages/search",
|
|
1091
1094
|
...options
|
|
@@ -1321,6 +1324,11 @@ var appPasswordsRevoke = (options) => (options.client ?? client).delete({
|
|
|
1321
1324
|
url: "/app-passwords/{id}",
|
|
1322
1325
|
...options
|
|
1323
1326
|
});
|
|
1327
|
+
var meGet = (options) => (options?.client ?? client).get({
|
|
1328
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1329
|
+
url: "/me",
|
|
1330
|
+
...options
|
|
1331
|
+
});
|
|
1324
1332
|
var workspaceGet = (options) => (options?.client ?? client).get({
|
|
1325
1333
|
security: [{ scheme: "bearer", type: "http" }],
|
|
1326
1334
|
url: "/workspace",
|
|
@@ -1336,6 +1344,11 @@ var eventsList = (options) => (options?.client ?? client).get({
|
|
|
1336
1344
|
url: "/events",
|
|
1337
1345
|
...options
|
|
1338
1346
|
});
|
|
1347
|
+
var eventsStream = (options) => (options?.client ?? client).sse.get({
|
|
1348
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1349
|
+
url: "/events/stream",
|
|
1350
|
+
...options
|
|
1351
|
+
});
|
|
1339
1352
|
var eventsGet = (options) => (options.client ?? client).get({
|
|
1340
1353
|
security: [{ scheme: "bearer", type: "http" }],
|
|
1341
1354
|
url: "/events/{id}",
|
|
@@ -1555,7 +1568,16 @@ var attachmentsDownloadUrl = (options) => (options.client ?? client).get({
|
|
|
1555
1568
|
var SIGNATURE_HEADER = "x-pidgeon-signature";
|
|
1556
1569
|
var TIMESTAMP_HEADER = "x-pidgeon-timestamp";
|
|
1557
1570
|
async function verifyWebhook(input) {
|
|
1558
|
-
const get = (name) =>
|
|
1571
|
+
const get = (name) => {
|
|
1572
|
+
if (input.headers instanceof Headers) return input.headers.get(name) ?? void 0;
|
|
1573
|
+
const direct = input.headers[name];
|
|
1574
|
+
if (direct !== void 0) return direct;
|
|
1575
|
+
const wanted = name.toLowerCase();
|
|
1576
|
+
for (const [key2, value] of Object.entries(input.headers)) {
|
|
1577
|
+
if (key2.toLowerCase() === wanted) return value;
|
|
1578
|
+
}
|
|
1579
|
+
return void 0;
|
|
1580
|
+
};
|
|
1559
1581
|
const timestamp = get(TIMESTAMP_HEADER);
|
|
1560
1582
|
const signature = get(SIGNATURE_HEADER);
|
|
1561
1583
|
if (!timestamp || !signature) throw new Error("This request is not signed.");
|
|
@@ -1592,6 +1614,103 @@ function constantTimeEqual(a, b) {
|
|
|
1592
1614
|
}
|
|
1593
1615
|
return difference === 0;
|
|
1594
1616
|
}
|
|
1617
|
+
async function* streamEvents(options) {
|
|
1618
|
+
const base = (options.baseUrl ?? "https://pidgeon.ai/api/v1").replace(/\/$/, "");
|
|
1619
|
+
let lastEventId;
|
|
1620
|
+
let backoffMs = 1e3;
|
|
1621
|
+
while (!options.signal?.aborted) {
|
|
1622
|
+
const url = new URL(`${base}/events/stream`);
|
|
1623
|
+
if (options.identityId) url.searchParams.set("identity_id", options.identityId);
|
|
1624
|
+
if (options.type) url.searchParams.set("type", options.type);
|
|
1625
|
+
if (options.after && !lastEventId) url.searchParams.set("after", options.after);
|
|
1626
|
+
let response;
|
|
1627
|
+
try {
|
|
1628
|
+
response = await fetch(url, {
|
|
1629
|
+
headers: {
|
|
1630
|
+
authorization: `Bearer ${options.apiKey}`,
|
|
1631
|
+
accept: "text/event-stream",
|
|
1632
|
+
...lastEventId ? { "last-event-id": lastEventId } : {}
|
|
1633
|
+
},
|
|
1634
|
+
signal: options.signal
|
|
1635
|
+
});
|
|
1636
|
+
} catch {
|
|
1637
|
+
if (options.signal?.aborted) return;
|
|
1638
|
+
await sleep(backoffMs, options.signal);
|
|
1639
|
+
backoffMs = Math.min(backoffMs * 2, 3e4);
|
|
1640
|
+
continue;
|
|
1641
|
+
}
|
|
1642
|
+
if (response.status === 401 || response.status === 403 || response.status === 404) {
|
|
1643
|
+
throw new Error(
|
|
1644
|
+
`Pidgeon refused the stream: ${response.status} ${await response.text().catch(() => "")}`.trim()
|
|
1645
|
+
);
|
|
1646
|
+
}
|
|
1647
|
+
if (!response.ok || !response.body) {
|
|
1648
|
+
await sleep(backoffMs, options.signal);
|
|
1649
|
+
backoffMs = Math.min(backoffMs * 2, 3e4);
|
|
1650
|
+
continue;
|
|
1651
|
+
}
|
|
1652
|
+
backoffMs = 1e3;
|
|
1653
|
+
for await (const frame of frames(response.body, options.signal)) {
|
|
1654
|
+
if (frame.id) lastEventId = frame.id;
|
|
1655
|
+
if (!frame.data) continue;
|
|
1656
|
+
if (frame.event === "error") continue;
|
|
1657
|
+
let parsed;
|
|
1658
|
+
try {
|
|
1659
|
+
parsed = JSON.parse(frame.data);
|
|
1660
|
+
} catch {
|
|
1661
|
+
continue;
|
|
1662
|
+
}
|
|
1663
|
+
yield parsed;
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
async function* frames(body, signal) {
|
|
1668
|
+
const reader = body.getReader();
|
|
1669
|
+
const decoder = new TextDecoder();
|
|
1670
|
+
let buffer = "";
|
|
1671
|
+
try {
|
|
1672
|
+
while (!signal?.aborted) {
|
|
1673
|
+
const { done, value } = await reader.read();
|
|
1674
|
+
if (done) return;
|
|
1675
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1676
|
+
let boundary = buffer.indexOf("\n\n");
|
|
1677
|
+
while (boundary !== -1) {
|
|
1678
|
+
const block = buffer.slice(0, boundary);
|
|
1679
|
+
buffer = buffer.slice(boundary + 2);
|
|
1680
|
+
boundary = buffer.indexOf("\n\n");
|
|
1681
|
+
const frame = {};
|
|
1682
|
+
const data = [];
|
|
1683
|
+
for (const line of block.split("\n")) {
|
|
1684
|
+
if (line.startsWith(":")) continue;
|
|
1685
|
+
const colon = line.indexOf(":");
|
|
1686
|
+
if (colon === -1) continue;
|
|
1687
|
+
const field = line.slice(0, colon);
|
|
1688
|
+
const value2 = line.slice(colon + 1).replace(/^ /, "");
|
|
1689
|
+
if (field === "id") frame.id = value2;
|
|
1690
|
+
else if (field === "event") frame.event = value2;
|
|
1691
|
+
else if (field === "data") data.push(value2);
|
|
1692
|
+
}
|
|
1693
|
+
if (data.length > 0) frame.data = data.join("\n");
|
|
1694
|
+
if (frame.id || frame.data) yield frame;
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
} finally {
|
|
1698
|
+
await reader.cancel().catch(() => void 0);
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
function sleep(ms, signal) {
|
|
1702
|
+
return new Promise((resolve) => {
|
|
1703
|
+
const timer = setTimeout(resolve, ms);
|
|
1704
|
+
signal?.addEventListener(
|
|
1705
|
+
"abort",
|
|
1706
|
+
() => {
|
|
1707
|
+
clearTimeout(timer);
|
|
1708
|
+
resolve();
|
|
1709
|
+
},
|
|
1710
|
+
{ once: true }
|
|
1711
|
+
);
|
|
1712
|
+
});
|
|
1713
|
+
}
|
|
1595
1714
|
|
|
1596
1715
|
// src/index.ts
|
|
1597
1716
|
var DEFAULT_BASE_URL = "https://pidgeon.ai/api/v1";
|
|
@@ -1726,4 +1845,4 @@ export {
|
|
|
1726
1845
|
find,
|
|
1727
1846
|
run
|
|
1728
1847
|
};
|
|
1729
|
-
//# sourceMappingURL=chunk-
|
|
1848
|
+
//# sourceMappingURL=chunk-IU5VSUXX.js.map
|