plaud-notes-to-notion 1.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.
- package/CHANGELOG.md +10 -0
- package/LICENSE +21 -0
- package/README.md +102 -0
- package/bin/plaud-notes-to-notion.js +16 -0
- package/dist/card.d.ts +30 -0
- package/dist/card.js +287 -0
- package/dist/card.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +266 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +41 -0
- package/dist/config.js +85 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +52 -0
- package/dist/constants.js +53 -0
- package/dist/constants.js.map +1 -0
- package/dist/daemon.d.ts +13 -0
- package/dist/daemon.js +182 -0
- package/dist/daemon.js.map +1 -0
- package/dist/format.d.ts +36 -0
- package/dist/format.js +108 -0
- package/dist/format.js.map +1 -0
- package/dist/ingest.d.ts +49 -0
- package/dist/ingest.js +205 -0
- package/dist/ingest.js.map +1 -0
- package/dist/llm.d.ts +65 -0
- package/dist/llm.js +177 -0
- package/dist/llm.js.map +1 -0
- package/dist/lock.d.ts +26 -0
- package/dist/lock.js +134 -0
- package/dist/lock.js.map +1 -0
- package/dist/log.d.ts +14 -0
- package/dist/log.js +41 -0
- package/dist/log.js.map +1 -0
- package/dist/notion.d.ts +86 -0
- package/dist/notion.js +254 -0
- package/dist/notion.js.map +1 -0
- package/dist/paths.d.ts +11 -0
- package/dist/paths.js +51 -0
- package/dist/paths.js.map +1 -0
- package/dist/plaud/callback.d.ts +19 -0
- package/dist/plaud/callback.js +162 -0
- package/dist/plaud/callback.js.map +1 -0
- package/dist/plaud/client.d.ts +55 -0
- package/dist/plaud/client.js +246 -0
- package/dist/plaud/client.js.map +1 -0
- package/dist/plaud/constants.d.ts +18 -0
- package/dist/plaud/constants.js +19 -0
- package/dist/plaud/constants.js.map +1 -0
- package/dist/plaud/errors.d.ts +10 -0
- package/dist/plaud/errors.js +32 -0
- package/dist/plaud/errors.js.map +1 -0
- package/dist/plaud/login.d.ts +17 -0
- package/dist/plaud/login.js +89 -0
- package/dist/plaud/login.js.map +1 -0
- package/dist/plaud/oauth.d.ts +21 -0
- package/dist/plaud/oauth.js +197 -0
- package/dist/plaud/oauth.js.map +1 -0
- package/dist/plaud/pkce.d.ts +3 -0
- package/dist/plaud/pkce.js +11 -0
- package/dist/plaud/pkce.js.map +1 -0
- package/dist/plaud/session.d.ts +23 -0
- package/dist/plaud/session.js +77 -0
- package/dist/plaud/session.js.map +1 -0
- package/dist/plaud/types.d.ts +21 -0
- package/dist/plaud/types.js +2 -0
- package/dist/plaud/types.js.map +1 -0
- package/dist/redact.d.ts +3 -0
- package/dist/redact.js +37 -0
- package/dist/redact.js.map +1 -0
- package/dist/runtime.d.ts +44 -0
- package/dist/runtime.js +94 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scrub.d.ts +17 -0
- package/dist/scrub.js +124 -0
- package/dist/scrub.js.map +1 -0
- package/dist/secrets.d.ts +59 -0
- package/dist/secrets.js +220 -0
- package/dist/secrets.js.map +1 -0
- package/dist/ssn.d.ts +33 -0
- package/dist/ssn.js +170 -0
- package/dist/ssn.js.map +1 -0
- package/dist/state.d.ts +46 -0
- package/dist/state.js +23 -0
- package/dist/state.js.map +1 -0
- package/dist/sync.d.ts +60 -0
- package/dist/sync.js +190 -0
- package/dist/sync.js.map +1 -0
- package/examples/com.plaud-notes-to-notion.plist +34 -0
- package/examples/install-launchagent.sh +16 -0
- package/package.json +37 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { gunzipSync } from "node:zlib";
|
|
2
|
+
import { AuthExpiredError, isAuthExpiredError, isTransportError } from "./errors.js";
|
|
3
|
+
import { redactSecrets } from "../redact.js";
|
|
4
|
+
function asString(value) {
|
|
5
|
+
if (typeof value === "string" && value.trim()) {
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
9
|
+
return String(value);
|
|
10
|
+
}
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
function asNumber(value) {
|
|
14
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
if (typeof value === "string" && value.trim() && Number.isFinite(Number(value))) {
|
|
18
|
+
return Number(value);
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Plaud's third-party API returns naive ISO strings that are UTC
|
|
24
|
+
* (e.g. start_at 2026-09-25T20:00:25 for a 3:00 PM CDT call); epoch seconds or
|
|
25
|
+
* milliseconds are accepted too.
|
|
26
|
+
*/
|
|
27
|
+
export function parsePlaudTime(value) {
|
|
28
|
+
const n = asNumber(value);
|
|
29
|
+
if (n !== null) {
|
|
30
|
+
const ms = n < 1e12 ? n * 1000 : n;
|
|
31
|
+
const d = new Date(ms);
|
|
32
|
+
return Number.isNaN(d.getTime()) ? null : d;
|
|
33
|
+
}
|
|
34
|
+
const s = asString(value);
|
|
35
|
+
if (!s) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const hasZone = /(?:Z|[+-]\d{2}:?\d{2})$/i.test(s.trim());
|
|
39
|
+
const d = new Date(hasZone ? s : `${s.trim().replace(" ", "T")}Z`);
|
|
40
|
+
return Number.isNaN(d.getTime()) ? null : d;
|
|
41
|
+
}
|
|
42
|
+
export function assertFileId(fileId) {
|
|
43
|
+
const id = typeof fileId === "string" ? fileId.trim() : "";
|
|
44
|
+
if (!/^[A-Za-z0-9_-]{1,128}$/.test(id)) {
|
|
45
|
+
throw new Error("Invalid Plaud file id");
|
|
46
|
+
}
|
|
47
|
+
return id;
|
|
48
|
+
}
|
|
49
|
+
function unwrap(payload) {
|
|
50
|
+
if (!payload || typeof payload !== "object") {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const obj = payload;
|
|
54
|
+
if (obj.data && typeof obj.data === "object" && !Array.isArray(obj.data)) {
|
|
55
|
+
const data = obj.data;
|
|
56
|
+
if (data.data && typeof data.data === "object" && !Array.isArray(data.data)) {
|
|
57
|
+
return data.data;
|
|
58
|
+
}
|
|
59
|
+
return data;
|
|
60
|
+
}
|
|
61
|
+
return obj;
|
|
62
|
+
}
|
|
63
|
+
export function extractFileList(payload) {
|
|
64
|
+
if (Array.isArray(payload)) {
|
|
65
|
+
return payload.filter((x) => x && typeof x === "object");
|
|
66
|
+
}
|
|
67
|
+
if (!payload || typeof payload !== "object") {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
const obj = payload;
|
|
71
|
+
const data = obj.data;
|
|
72
|
+
for (const c of [obj.data_list, obj.files, obj.items, obj.data, data?.data_list, data?.files, data?.items, data?.data]) {
|
|
73
|
+
if (Array.isArray(c)) {
|
|
74
|
+
return c.filter((x) => x && typeof x === "object");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
export function normalizeListing(raw) {
|
|
80
|
+
const id = asString(raw.id) || asString(raw.file_id);
|
|
81
|
+
if (!id) {
|
|
82
|
+
throw new Error("Plaud file payload missing id");
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
id,
|
|
86
|
+
name: asString(raw.name) || asString(raw.filename) || asString(raw.title) || "Untitled recording",
|
|
87
|
+
createdAt: parsePlaudTime(raw.created_at ?? raw.createdAt ?? raw.start_at),
|
|
88
|
+
startAt: parsePlaudTime(raw.start_at ?? raw.startAt ?? raw.start_time),
|
|
89
|
+
durationMs: asNumber(raw.duration) ?? asNumber(raw.duration_ms)
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export function segmentsFromUnknown(list) {
|
|
93
|
+
if (!Array.isArray(list)) {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
const out = [];
|
|
97
|
+
for (const item of list) {
|
|
98
|
+
if (!item || typeof item !== "object") {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const rec = item;
|
|
102
|
+
const text = asString(rec.content) ?? asString(rec.text) ?? asString(rec.sentence);
|
|
103
|
+
if (!text) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
out.push({
|
|
107
|
+
speaker: asString(rec.speaker) || asString(rec.original_speaker) || "Speaker",
|
|
108
|
+
startMs: asNumber(rec.start_time) ?? asNumber(rec.start) ?? asNumber(rec.start_ms) ?? 0,
|
|
109
|
+
text
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
function decodeBlock(buf) {
|
|
115
|
+
const bytes = buf[0] === 0x1f && buf[1] === 0x8b ? gunzipSync(buf) : buf;
|
|
116
|
+
return bytes.toString("utf8");
|
|
117
|
+
}
|
|
118
|
+
const MAX_BLOCK_BYTES = 30 * 1024 * 1024;
|
|
119
|
+
export async function fetchHttpsBlock(rawUrl, fetchImpl = fetch) {
|
|
120
|
+
const url = new URL(rawUrl);
|
|
121
|
+
if (url.protocol !== "https:" || url.username || url.password) {
|
|
122
|
+
throw new Error("Plaud block URL must be plain https");
|
|
123
|
+
}
|
|
124
|
+
const ctrl = new AbortController();
|
|
125
|
+
const timer = setTimeout(() => ctrl.abort(), 60_000);
|
|
126
|
+
try {
|
|
127
|
+
const res = await fetchImpl(url, { redirect: "error", signal: ctrl.signal });
|
|
128
|
+
if (!res.ok) {
|
|
129
|
+
throw new Error(`Plaud block fetch HTTP ${res.status}`);
|
|
130
|
+
}
|
|
131
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
132
|
+
if (buf.byteLength > MAX_BLOCK_BYTES) {
|
|
133
|
+
throw new Error("Plaud block too large");
|
|
134
|
+
}
|
|
135
|
+
return decodeBlock(buf);
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
clearTimeout(timer);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
export class HttpPlaudClient {
|
|
142
|
+
session;
|
|
143
|
+
fetchImpl;
|
|
144
|
+
baseUrl;
|
|
145
|
+
constructor(session, options = {}) {
|
|
146
|
+
this.session = session;
|
|
147
|
+
this.fetchImpl = options.fetchImpl || fetch;
|
|
148
|
+
this.baseUrl = (options.baseUrl || session.endpoints.apiBase).replace(/\/$/, "");
|
|
149
|
+
}
|
|
150
|
+
async listFiles(page = 1, pageSize = 20) {
|
|
151
|
+
const payload = await this.requestJson(`/open/third-party/files/?page=${page}&page_size=${Math.max(10, pageSize)}`);
|
|
152
|
+
return extractFileList(payload).map(normalizeListing);
|
|
153
|
+
}
|
|
154
|
+
async currentUser() {
|
|
155
|
+
return unwrap(await this.requestJson("/open/third-party/users/current")) || {};
|
|
156
|
+
}
|
|
157
|
+
async getRecording(fileId) {
|
|
158
|
+
const id = assertFileId(fileId);
|
|
159
|
+
const record = unwrap(await this.requestJson(`/open/third-party/files/${encodeURIComponent(id)}`));
|
|
160
|
+
if (!record) {
|
|
161
|
+
throw new Error("Plaud file not found");
|
|
162
|
+
}
|
|
163
|
+
const listing = normalizeListing(record);
|
|
164
|
+
return {
|
|
165
|
+
...listing,
|
|
166
|
+
summaryMarkdown: await this.autoSummary(record),
|
|
167
|
+
segments: await this.transcriptSegments(record)
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
async blockContent(block) {
|
|
171
|
+
const inline = asString(block.data_content);
|
|
172
|
+
if (inline) {
|
|
173
|
+
return inline;
|
|
174
|
+
}
|
|
175
|
+
const link = asString(block.data_link);
|
|
176
|
+
return link ? fetchHttpsBlock(link, this.fetchImpl) : "";
|
|
177
|
+
}
|
|
178
|
+
/** The Summary tab (`auto_sum_note`) — what the Zap's "Summary" field carried. */
|
|
179
|
+
async autoSummary(record) {
|
|
180
|
+
const notes = Array.isArray(record.note_list) ? record.note_list : [];
|
|
181
|
+
const note = notes.find((n) => n && n.data_type === "auto_sum_note");
|
|
182
|
+
if (!note) {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
const text = (await this.blockContent(note)).trim();
|
|
186
|
+
return text || null;
|
|
187
|
+
}
|
|
188
|
+
async transcriptSegments(record) {
|
|
189
|
+
const sources = Array.isArray(record.source_list) ? record.source_list : [];
|
|
190
|
+
const block = sources.find((s) => s && s.data_type === "transaction");
|
|
191
|
+
if (!block) {
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
const content = await this.blockContent(block);
|
|
195
|
+
if (!content.trim()) {
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
const parsed = JSON.parse(content);
|
|
200
|
+
const list = Array.isArray(parsed) ? parsed : parsed?.segments ?? parsed?.data;
|
|
201
|
+
return segmentsFromUnknown(list);
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return [];
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
async requestJson(pathname, retried = false) {
|
|
208
|
+
const token = await this.session.getAccessToken();
|
|
209
|
+
if (!token) {
|
|
210
|
+
throw new AuthExpiredError();
|
|
211
|
+
}
|
|
212
|
+
let res;
|
|
213
|
+
try {
|
|
214
|
+
res = await this.fetchImpl(`${this.baseUrl}${pathname}`, {
|
|
215
|
+
method: "GET",
|
|
216
|
+
headers: { Authorization: `Bearer ${token}`, Accept: "application/json" },
|
|
217
|
+
signal: AbortSignal.timeout(60_000)
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
catch (err) {
|
|
221
|
+
throw isTransportError(err) ? err : new Error(redactSecrets(String(err)));
|
|
222
|
+
}
|
|
223
|
+
if (res.status === 401 && !retried) {
|
|
224
|
+
try {
|
|
225
|
+
await this.session.refresh();
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
if (isTransportError(err) || isAuthExpiredError(err)) {
|
|
229
|
+
throw err;
|
|
230
|
+
}
|
|
231
|
+
throw new AuthExpiredError();
|
|
232
|
+
}
|
|
233
|
+
return this.requestJson(pathname, true);
|
|
234
|
+
}
|
|
235
|
+
if (res.status === 401 || res.status === 403) {
|
|
236
|
+
throw new AuthExpiredError();
|
|
237
|
+
}
|
|
238
|
+
if (!res.ok) {
|
|
239
|
+
const err = new Error(`Plaud API HTTP ${res.status} for ${pathname.split("?")[0]}`);
|
|
240
|
+
err.transient = res.status >= 500 || res.status === 429;
|
|
241
|
+
throw err;
|
|
242
|
+
}
|
|
243
|
+
return res.json();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/plaud/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAErF,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAgC7C,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACxD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAChF,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QACf,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;QACvB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;IACD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,OAAO,GAAG,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACnE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,MAAM,EAAE,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,MAAM,CAAC,OAAgB;IAC9B,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,GAAG,GAAG,OAAkC,CAAC;IAC/C,IAAI,GAAG,CAAC,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QACjD,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5E,OAAO,IAAI,CAAC,IAA+B,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,CAA8B,CAAC;IACxF,CAAC;IACD,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,GAAG,GAAG,OAAkC,CAAC;IAC/C,MAAM,IAAI,GAAG,GAAG,CAAC,IAA2C,CAAC;IAC7D,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QACvH,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,CAA8B,CAAC;QAClF,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAA4B;IAC3D,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrD,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IACD,OAAO;QACL,EAAE;QACF,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,oBAAoB;QACjG,SAAS,EAAE,cAAc,CAAC,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,QAAQ,CAAC;QAC1E,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,UAAU,CAAC;QACtE,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC;KAChE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAa;IAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtC,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,IAA+B,CAAC;QAC5C,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnF,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,SAAS;YAC7E,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;YACvF,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACzE,OAAO,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,eAAe,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAc,EAAE,YAA0B,KAAK;IACnF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;IACrD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7E,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACjD,IAAI,GAAG,CAAC,UAAU,GAAG,eAAe,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,MAAM,OAAO,eAAe;IAKP;IAJF,SAAS,CAAe;IACxB,OAAO,CAAS;IAEjC,YACmB,OAAyB,EAC1C,UAA0D,EAAE;QAD3C,YAAO,GAAP,OAAO,CAAkB;QAG1C,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;QAC5C,IAAI,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACnF,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,EAAE,QAAQ,GAAG,EAAE;QACrC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,iCAAiC,IAAI,cAAc,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QACpH,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,iCAAiC,CAAC,CAAC,IAAI,EAAE,CAAC;IACjF,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAc;QAC/B,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,2BAA2B,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACnG,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACzC,OAAO;YACL,GAAG,OAAO;YACV,eAAe,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;YAC/C,QAAQ,EAAE,MAAM,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC;SAChD,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,KAA8B;QACvD,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,CAAC;IAED,kFAAkF;IAC1E,KAAK,CAAC,WAAW,CAAC,MAA+B;QACvD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAE,MAAM,CAAC,SAAuC,CAAC,CAAC,CAAC,EAAE,CAAC;QACrG,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,eAAe,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACpD,OAAO,IAAI,IAAI,IAAI,CAAC;IACtB,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,MAA+B;QAC9D,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAE,MAAM,CAAC,WAAyC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3G,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,aAAa,CAAC,CAAC;QACtE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YACpB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;YAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAE,MAAkC,EAAE,QAAQ,IAAK,MAAkC,EAAE,IAAI,CAAC;YACzI,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,QAAgB,EAAE,OAAO,GAAG,KAAK;QACzD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAClD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,gBAAgB,EAAE,CAAC;QAC/B,CAAC;QACD,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,QAAQ,EAAE,EAAE;gBACvD,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;gBACzE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;aACpC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC/B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;oBACrD,MAAM,GAAG,CAAC;gBACZ,CAAC;gBACD,MAAM,IAAI,gBAAgB,EAAE,CAAC;YAC/B,CAAC;YACD,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC7C,MAAM,IAAI,gBAAgB,EAAE,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,MAAM,QAAQ,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnF,GAA+B,CAAC,SAAS,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC;YACrF,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plaud consumer MCP OAuth — same public-client defaults as `@plaud-ai/mcp`
|
|
3
|
+
* (and Plaud-Index-MCP). Published identifiers/URLs, not secrets.
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEFAULT_MCP_CLIENT_ID = "client_9c501dad-8a0d-40b2-a7b0-d1cb8787f674";
|
|
6
|
+
export declare const DEFAULT_AUTHORIZATION_URL = "https://web.plaud.ai/platform/oauth";
|
|
7
|
+
export declare const DEFAULT_TOKEN_URL = "https://platform.plaud.ai/developer/api/oauth/third-party/access-token";
|
|
8
|
+
export declare const DEFAULT_REFRESH_URL = "https://platform.plaud.ai/developer/api/oauth/third-party/access-token/refresh";
|
|
9
|
+
/** Data plane behind the Plaud MCP tools (`list_files` / `get_file`). */
|
|
10
|
+
export declare const DEFAULT_MCP_API_BASE = "https://platform.plaud.ai/developer/api";
|
|
11
|
+
/** Plaud's registered loopback redirect for this public client. */
|
|
12
|
+
export declare const OAUTH_CALLBACK_PORT = 8199;
|
|
13
|
+
export declare const OAUTH_CALLBACK_PATH = "/auth/callback";
|
|
14
|
+
export declare const OAUTH_REDIRECT_URI = "http://localhost:8199/auth/callback";
|
|
15
|
+
export declare const LOGIN_TIMEOUT_MS = 180000;
|
|
16
|
+
export declare const REFRESH_SKEW_MS = 60000;
|
|
17
|
+
export declare const RELLOGIN_MESSAGE = "Plaud sign-in expired. Re-run: plaud-notes-to-notion login --profile <name>";
|
|
18
|
+
export declare const AUTH_TRANSIENT_MESSAGE = "Cannot reach Plaud (network or server error). Will retry next cycle; tokens were not cleared.";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plaud consumer MCP OAuth — same public-client defaults as `@plaud-ai/mcp`
|
|
3
|
+
* (and Plaud-Index-MCP). Published identifiers/URLs, not secrets.
|
|
4
|
+
*/
|
|
5
|
+
export const DEFAULT_MCP_CLIENT_ID = "client_9c501dad-8a0d-40b2-a7b0-d1cb8787f674";
|
|
6
|
+
export const DEFAULT_AUTHORIZATION_URL = "https://web.plaud.ai/platform/oauth";
|
|
7
|
+
export const DEFAULT_TOKEN_URL = "https://platform.plaud.ai/developer/api/oauth/third-party/access-token";
|
|
8
|
+
export const DEFAULT_REFRESH_URL = "https://platform.plaud.ai/developer/api/oauth/third-party/access-token/refresh";
|
|
9
|
+
/** Data plane behind the Plaud MCP tools (`list_files` / `get_file`). */
|
|
10
|
+
export const DEFAULT_MCP_API_BASE = "https://platform.plaud.ai/developer/api";
|
|
11
|
+
/** Plaud's registered loopback redirect for this public client. */
|
|
12
|
+
export const OAUTH_CALLBACK_PORT = 8199;
|
|
13
|
+
export const OAUTH_CALLBACK_PATH = "/auth/callback";
|
|
14
|
+
export const OAUTH_REDIRECT_URI = `http://localhost:${OAUTH_CALLBACK_PORT}${OAUTH_CALLBACK_PATH}`;
|
|
15
|
+
export const LOGIN_TIMEOUT_MS = 180_000;
|
|
16
|
+
export const REFRESH_SKEW_MS = 60_000;
|
|
17
|
+
export const RELLOGIN_MESSAGE = "Plaud sign-in expired. Re-run: plaud-notes-to-notion login --profile <name>";
|
|
18
|
+
export const AUTH_TRANSIENT_MESSAGE = "Cannot reach Plaud (network or server error). Will retry next cycle; tokens were not cleared.";
|
|
19
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/plaud/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,6CAA6C,CAAC;AACnF,MAAM,CAAC,MAAM,yBAAyB,GAAG,qCAAqC,CAAC;AAC/E,MAAM,CAAC,MAAM,iBAAiB,GAAG,wEAAwE,CAAC;AAC1G,MAAM,CAAC,MAAM,mBAAmB,GAC9B,gFAAgF,CAAC;AACnF,yEAAyE;AACzE,MAAM,CAAC,MAAM,oBAAoB,GAAG,yCAAyC,CAAC;AAE9E,mEAAmE;AACnE,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AACxC,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AACpD,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,mBAAmB,GAAG,mBAAmB,EAAE,CAAC;AAClG,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AACxC,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC;AAEtC,MAAM,CAAC,MAAM,gBAAgB,GAAG,6EAA6E,CAAC;AAC9G,MAAM,CAAC,MAAM,sBAAsB,GACjC,+FAA+F,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare class AuthExpiredError extends Error {
|
|
2
|
+
readonly code = "AUTH_EXPIRED";
|
|
3
|
+
constructor(message?: string);
|
|
4
|
+
}
|
|
5
|
+
export declare class AuthTransportError extends Error {
|
|
6
|
+
readonly code = "AUTH_TRANSPORT";
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
export declare function isAuthExpiredError(err: unknown): boolean;
|
|
10
|
+
export declare function isTransportError(err: unknown): boolean;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { RELLOGIN_MESSAGE } from "./constants.js";
|
|
2
|
+
export class AuthExpiredError extends Error {
|
|
3
|
+
code = "AUTH_EXPIRED";
|
|
4
|
+
constructor(message = RELLOGIN_MESSAGE) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "AuthExpiredError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export class AuthTransportError extends Error {
|
|
10
|
+
code = "AUTH_TRANSPORT";
|
|
11
|
+
constructor(message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = "AuthTransportError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function isAuthExpiredError(err) {
|
|
17
|
+
return err instanceof AuthExpiredError || (err instanceof Error && err.name === "AuthExpiredError");
|
|
18
|
+
}
|
|
19
|
+
export function isTransportError(err) {
|
|
20
|
+
if (err instanceof AuthTransportError) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
const e = err instanceof Error ? err : undefined;
|
|
24
|
+
const msg = e ? e.message : String(err ?? "");
|
|
25
|
+
const name = e ? e.name : "";
|
|
26
|
+
if (name === "AbortError" || /\btimeout\b|ETIMEDOUT/i.test(msg)) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
return (err instanceof TypeError ||
|
|
30
|
+
/fetch failed|ECONNREFUSED|ENOTFOUND|ECONNRESET|EAI_AGAIN|network/i.test(msg));
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/plaud/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,IAAI,GAAG,cAAc,CAAC;IAE/B,YAAY,UAAkB,gBAAgB;QAC5C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAClC,IAAI,GAAG,gBAAgB,CAAC;IAEjC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,OAAO,GAAG,YAAY,gBAAgB,IAAI,CAAC,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC;AACtG,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,IAAI,GAAG,YAAY,kBAAkB,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,CAAC,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACjD,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7B,IAAI,IAAI,KAAK,YAAY,IAAI,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CACL,GAAG,YAAY,SAAS;QACxB,mEAAmE,CAAC,IAAI,CAAC,GAAG,CAAC,CAC9E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SecretStore } from "../secrets.js";
|
|
2
|
+
export declare function openBrowser(url: string, platform?: NodeJS.Platform): void;
|
|
3
|
+
export declare function probeCurrentUser(options: {
|
|
4
|
+
token: string;
|
|
5
|
+
apiBase: string;
|
|
6
|
+
fetchImpl?: typeof fetch;
|
|
7
|
+
}): Promise<"ok" | "unauthorized" | "error">;
|
|
8
|
+
/** Plaud consumer OAuth (public client + PKCE) for one profile; tokens go to Keychain. */
|
|
9
|
+
export declare function runPlaudLogin(options: {
|
|
10
|
+
profile: string;
|
|
11
|
+
store: SecretStore;
|
|
12
|
+
account: string;
|
|
13
|
+
noBrowser?: boolean;
|
|
14
|
+
env?: NodeJS.ProcessEnv;
|
|
15
|
+
fetchImpl?: typeof fetch;
|
|
16
|
+
log?: (msg: string) => void;
|
|
17
|
+
}): Promise<number>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { runOAuthCallback } from "./callback.js";
|
|
3
|
+
import { LOGIN_TIMEOUT_MS, OAUTH_CALLBACK_PORT } from "./constants.js";
|
|
4
|
+
import { createAuthorizationRequest, exchangeAuthorizationCode } from "./oauth.js";
|
|
5
|
+
import { createAuthSession } from "./session.js";
|
|
6
|
+
import { redactSecrets } from "../redact.js";
|
|
7
|
+
export function openBrowser(url, platform = process.platform) {
|
|
8
|
+
const cmd = platform === "darwin" ? "open" : "xdg-open";
|
|
9
|
+
const child = spawn(cmd, [url], { detached: true, stdio: "ignore" });
|
|
10
|
+
child.unref();
|
|
11
|
+
}
|
|
12
|
+
export async function probeCurrentUser(options) {
|
|
13
|
+
try {
|
|
14
|
+
const res = await (options.fetchImpl || fetch)(`${options.apiBase.replace(/\/$/, "")}/open/third-party/users/current`, { headers: { Authorization: `Bearer ${options.token}`, Accept: "application/json" } });
|
|
15
|
+
if (res.status === 401 || res.status === 403) {
|
|
16
|
+
return "unauthorized";
|
|
17
|
+
}
|
|
18
|
+
return res.ok ? "ok" : "error";
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return "error";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Plaud consumer OAuth (public client + PKCE) for one profile; tokens go to Keychain. */
|
|
25
|
+
export async function runPlaudLogin(options) {
|
|
26
|
+
const log = options.log || ((msg) => console.error(msg));
|
|
27
|
+
const session = await createAuthSession({
|
|
28
|
+
store: options.store,
|
|
29
|
+
account: options.account,
|
|
30
|
+
env: options.env,
|
|
31
|
+
fetchImpl: options.fetchImpl
|
|
32
|
+
});
|
|
33
|
+
const endpoints = session.endpoints;
|
|
34
|
+
const existing = await session.getAccessToken().catch(() => null);
|
|
35
|
+
if (existing) {
|
|
36
|
+
const probe = await probeCurrentUser({ token: existing, apiBase: endpoints.apiBase, fetchImpl: options.fetchImpl });
|
|
37
|
+
if (probe === "ok") {
|
|
38
|
+
log(`Profile ${options.profile} is already signed in to Plaud (${options.store.describe()}).`);
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
if (probe === "error") {
|
|
42
|
+
log("Cannot reach Plaud to check the saved sign-in. Try again when the network is up.");
|
|
43
|
+
return 1;
|
|
44
|
+
}
|
|
45
|
+
await session.clear();
|
|
46
|
+
}
|
|
47
|
+
const request = createAuthorizationRequest(endpoints);
|
|
48
|
+
log(`Plaud sign-in for profile "${options.profile}". Sign in as that person's Plaud account, then click Authorize.`);
|
|
49
|
+
log(request.url);
|
|
50
|
+
log(`Waiting up to ${Math.round(LOGIN_TIMEOUT_MS / 60_000)} minutes for the callback on localhost:${OAUTH_CALLBACK_PORT}…`);
|
|
51
|
+
if (!options.noBrowser) {
|
|
52
|
+
try {
|
|
53
|
+
openBrowser(request.url);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
log("Could not open a browser. Open the URL above on this Mac.");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const result = await runOAuthCallback({
|
|
60
|
+
expectedState: request.state,
|
|
61
|
+
timeoutMs: LOGIN_TIMEOUT_MS,
|
|
62
|
+
exchangeCode: async (code) => {
|
|
63
|
+
const tokenSet = await exchangeAuthorizationCode({
|
|
64
|
+
endpoints,
|
|
65
|
+
code,
|
|
66
|
+
codeVerifier: request.codeVerifier,
|
|
67
|
+
state: request.state,
|
|
68
|
+
fetchImpl: options.fetchImpl
|
|
69
|
+
});
|
|
70
|
+
await session.save(tokenSet);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
if (result.status !== "success") {
|
|
74
|
+
log(redactSecrets(`Plaud sign-in did not finish (${result.status}${result.error ? `: ${result.error.message}` : ""}).`));
|
|
75
|
+
return 1;
|
|
76
|
+
}
|
|
77
|
+
const token = await session.getAccessToken();
|
|
78
|
+
const probe = token
|
|
79
|
+
? await probeCurrentUser({ token, apiBase: endpoints.apiBase, fetchImpl: options.fetchImpl })
|
|
80
|
+
: "unauthorized";
|
|
81
|
+
if (probe !== "ok") {
|
|
82
|
+
await session.clear();
|
|
83
|
+
log("Plaud accepted the sign-in but the API rejected the token. Nothing was saved.");
|
|
84
|
+
return 1;
|
|
85
|
+
}
|
|
86
|
+
log(`Signed in. Plaud tokens for profile ${options.profile} are in ${options.store.describe()}; the service refreshes them on its own.`);
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/plaud/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AuthorizationRequest, OAuthEndpoints, PlaudTokenSet } from "./types.js";
|
|
2
|
+
export declare function resolveOAuthEndpoints(env?: NodeJS.ProcessEnv): OAuthEndpoints;
|
|
3
|
+
export declare function createAuthorizationRequest(endpoints: OAuthEndpoints): AuthorizationRequest;
|
|
4
|
+
export declare function parseTokenSet(data: unknown, nowMs: number, previous?: PlaudTokenSet | null): PlaudTokenSet;
|
|
5
|
+
export declare function parseStoredTokenSet(raw: string): PlaudTokenSet | null;
|
|
6
|
+
export declare function serializeTokenSet(tokenSet: PlaudTokenSet): string;
|
|
7
|
+
export declare function tokenNeedsRefresh(tokenSet: PlaudTokenSet, nowMs: number, skewMs: number): boolean;
|
|
8
|
+
export declare function exchangeAuthorizationCode(options: {
|
|
9
|
+
endpoints: OAuthEndpoints;
|
|
10
|
+
code: string;
|
|
11
|
+
codeVerifier: string;
|
|
12
|
+
state: string;
|
|
13
|
+
fetchImpl?: typeof fetch;
|
|
14
|
+
now?: () => number;
|
|
15
|
+
}): Promise<PlaudTokenSet>;
|
|
16
|
+
export declare function refreshTokenSet(options: {
|
|
17
|
+
endpoints: OAuthEndpoints;
|
|
18
|
+
tokenSet: PlaudTokenSet;
|
|
19
|
+
fetchImpl?: typeof fetch;
|
|
20
|
+
now?: () => number;
|
|
21
|
+
}): Promise<PlaudTokenSet>;
|