plaud 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAM7B,SAAS,YAAY;IACnB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACxC,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAE,MAAsB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAmB;IACnD,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7C,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,iFAAiF;IACjF,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAC9D,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE;QAAE,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC;IACvD,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACnD,CAAC"}
@@ -0,0 +1,88 @@
1
+ import fs from "node:fs/promises";
2
+ import { createWriteStream } from "node:fs";
3
+ import path from "node:path";
4
+ import { Readable } from "node:stream";
5
+ import { getRecordingTempUrls, getRecordingDetailsBatch } from "./plaud-api.js";
6
+ import { formatTranscript, getFilenameWithDate, sanitizeFilename } from "./recordings-format.js";
7
+ async function ensureDir(dir) {
8
+ await fs.mkdir(dir, { recursive: true });
9
+ }
10
+ async function streamToFile({ url, outPath, timeoutMs = 60_000, }) {
11
+ const controller = new AbortController();
12
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
13
+ try {
14
+ const res = await fetch(url, { signal: controller.signal });
15
+ if (!res.ok)
16
+ throw new Error(`Download failed: HTTP ${res.status} ${res.statusText}`);
17
+ if (!res.body)
18
+ throw new Error("Download failed: empty body");
19
+ await ensureDir(path.dirname(outPath));
20
+ const fileStream = createWriteStream(outPath);
21
+ await new Promise((resolve, reject) => {
22
+ fileStream.on("error", reject);
23
+ fileStream.on("close", resolve);
24
+ Readable.fromWeb(res.body).pipe(fileStream);
25
+ });
26
+ return { bytes: Number(res.headers.get("content-length") || 0) || null };
27
+ }
28
+ finally {
29
+ clearTimeout(timeout);
30
+ }
31
+ }
32
+ async function getDetails({ token, id }) {
33
+ const list = await getRecordingDetailsBatch({ token, ids: [id] });
34
+ const details = Array.isArray(list) ? list.find((d) => String(d?.id || "") === String(id)) : null;
35
+ if (!details)
36
+ throw new Error("Recording not found (or details unavailable)");
37
+ return details;
38
+ }
39
+ function parseWhat(what) {
40
+ const parts = String(what || "")
41
+ .split(",")
42
+ .map((s) => s.trim().toLowerCase())
43
+ .filter(Boolean);
44
+ return new Set(parts.length ? parts : ["transcript", "summary", "json"]);
45
+ }
46
+ export async function downloadRecording({ token, id, outDir, what = "transcript,summary,json", audioFormat = "opus", }) {
47
+ if (!token)
48
+ throw new Error("Missing token");
49
+ if (!id)
50
+ throw new Error("Missing id");
51
+ if (!outDir)
52
+ throw new Error("Missing outDir");
53
+ const whatSet = parseWhat(what);
54
+ const details = await getDetails({ token, id });
55
+ const baseFilename = getFilenameWithDate(details?.filename, { id }, details);
56
+ const written = [];
57
+ await ensureDir(outDir);
58
+ if (whatSet.has("json")) {
59
+ const jsonPath = path.join(outDir, `${baseFilename}.json`);
60
+ await fs.writeFile(jsonPath, JSON.stringify(details, null, 2), "utf8");
61
+ written.push({ kind: "json", path: jsonPath });
62
+ }
63
+ if (whatSet.has("transcript")) {
64
+ const transcript = formatTranscript(details?.trans_result);
65
+ const transcriptPath = path.join(outDir, `${baseFilename}.txt`);
66
+ await fs.writeFile(transcriptPath, transcript, "utf8");
67
+ written.push({ kind: "transcript", path: transcriptPath });
68
+ }
69
+ if (whatSet.has("summary")) {
70
+ const ai = details?.ai_content ? String(details.ai_content) : "";
71
+ const mdPath = path.join(outDir, `${baseFilename}_ai.md`);
72
+ await fs.writeFile(mdPath, ai, "utf8");
73
+ written.push({ kind: "summary", path: mdPath });
74
+ }
75
+ if (whatSet.has("audio")) {
76
+ const temp = await getRecordingTempUrls({ token, id });
77
+ const tempUrl = audioFormat === "original" ? temp?.temp_url : temp?.temp_url_opus || temp?.temp_url;
78
+ if (!tempUrl)
79
+ throw new Error("Audio temp URL not available for this recording");
80
+ const ext = audioFormat === "opus" ? "opus" : "m4a";
81
+ const audioName = sanitizeFilename(`${baseFilename}.${ext}`);
82
+ const audioPath = path.join(outDir, audioName);
83
+ const info = await streamToFile({ url: tempUrl, outPath: audioPath });
84
+ written.push({ kind: "audio", path: audioPath, bytes: info.bytes });
85
+ }
86
+ return { id: String(id), outDir, written };
87
+ }
88
+ //# sourceMappingURL=download.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.js","sourceRoot":"","sources":["../src/download.ts"],"names":[],"mappings":"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"}
package/dist/export.js ADDED
@@ -0,0 +1,164 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import archiver from "archiver";
4
+ import { createWriteStream } from "node:fs";
5
+ import { listRecordings, getRecordingDetailsBatch } from "./plaud-api.js";
6
+ import { formatTranscript, getFilenameWithDate } from "./recordings-format.js";
7
+ function sleep(ms) {
8
+ return new Promise((resolve) => setTimeout(resolve, ms));
9
+ }
10
+ function parseIsoDate(value) {
11
+ if (!value)
12
+ return null;
13
+ const d = new Date(value);
14
+ if (Number.isNaN(d.getTime()))
15
+ return null;
16
+ return d;
17
+ }
18
+ async function ensureDir(dir) {
19
+ await fs.mkdir(dir, { recursive: true });
20
+ }
21
+ async function exists(p) {
22
+ try {
23
+ await fs.stat(p);
24
+ return true;
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ }
30
+ export async function exportRecordings({ token, outDir, zipPath, includeTrash = false, formats = { txt: true, json: true, md: true }, batchSize = 10, delayMs = 300, max = Infinity, since, until, resume = false, onProgress, }) {
31
+ const sinceDate = parseIsoDate(since || null);
32
+ const untilDate = parseIsoDate(until || null);
33
+ const recordings = await listRecordings({ token, includeTrash, max });
34
+ const filtered = recordings.filter((r) => {
35
+ const ts = r?.start_time || r?.edit_time;
36
+ if (!ts)
37
+ return true;
38
+ const d = new Date(ts);
39
+ if (Number.isNaN(d.getTime()))
40
+ return true;
41
+ if (sinceDate && d < sinceDate)
42
+ return false;
43
+ if (untilDate && d > untilDate)
44
+ return false;
45
+ return true;
46
+ });
47
+ const progress = { current: 0, total: filtered.length };
48
+ const results = [];
49
+ let archive = null;
50
+ let archiveStream = null;
51
+ if (zipPath) {
52
+ await ensureDir(path.dirname(zipPath));
53
+ archiveStream = createWriteStream(zipPath);
54
+ archive = archiver("zip", { zlib: { level: 6 } });
55
+ archive.on("warning", (err) => {
56
+ // eslint-disable-next-line no-console
57
+ console.warn("zip warning:", err?.message || err);
58
+ });
59
+ archive.on("error", (err) => {
60
+ throw err;
61
+ });
62
+ archive.pipe(archiveStream);
63
+ }
64
+ else {
65
+ await ensureDir(outDir);
66
+ await ensureDir(path.join(outDir, "transcripts"));
67
+ await ensureDir(path.join(outDir, "json"));
68
+ await ensureDir(path.join(outDir, "ai-summaries"));
69
+ }
70
+ for (let i = 0; i < filtered.length; i += batchSize) {
71
+ const batch = filtered.slice(i, i + batchSize);
72
+ const ids = batch.map((f) => f.id).filter(Boolean);
73
+ let detailsList = [];
74
+ try {
75
+ detailsList = await getRecordingDetailsBatch({ token, ids });
76
+ }
77
+ catch {
78
+ // If the batch call fails, fall back to single-id requests for this batch.
79
+ detailsList = [];
80
+ for (const id of ids) {
81
+ try {
82
+ const single = await getRecordingDetailsBatch({ token, ids: [id] });
83
+ detailsList.push(...single);
84
+ }
85
+ catch {
86
+ // leave missing
87
+ }
88
+ }
89
+ }
90
+ const detailsById = new Map(detailsList.map((d) => [d.id, d]));
91
+ for (const file of batch) {
92
+ const details = detailsById.get(file.id) || null;
93
+ const filename = getFilenameWithDate(file.filename, file, details);
94
+ try {
95
+ const transcriptText = formats.txt ? formatTranscript(details?.trans_result) : null;
96
+ const jsonText = formats.json ? JSON.stringify(details ?? {}, null, 2) : null;
97
+ const aiText = formats.md ? (details?.ai_content ? String(details.ai_content) : "") : null;
98
+ const jsonRel = `json/${filename}.json`;
99
+ const txtRel = `transcripts/${filename}.txt`;
100
+ const mdRel = `ai-summaries/${filename}_ai.md`;
101
+ if (archive) {
102
+ if (formats.json)
103
+ archive.append(jsonText, { name: jsonRel });
104
+ if (formats.txt && transcriptText)
105
+ archive.append(transcriptText, { name: txtRel });
106
+ if (formats.md && aiText)
107
+ archive.append(aiText, { name: mdRel });
108
+ }
109
+ else {
110
+ const jsonPath = path.join(outDir, jsonRel);
111
+ const txtPath = path.join(outDir, txtRel);
112
+ const mdPath = path.join(outDir, mdRel);
113
+ if (formats.json) {
114
+ if (!resume || !(await exists(jsonPath)))
115
+ await fs.writeFile(jsonPath, jsonText || "{}", "utf8");
116
+ }
117
+ if (formats.txt && transcriptText) {
118
+ if (!resume || !(await exists(txtPath)))
119
+ await fs.writeFile(txtPath, transcriptText, "utf8");
120
+ }
121
+ if (formats.md && aiText) {
122
+ if (!resume || !(await exists(mdPath)))
123
+ await fs.writeFile(mdPath, aiText, "utf8");
124
+ }
125
+ }
126
+ results.push({ success: true, id: String(file.id), filename: file.filename });
127
+ }
128
+ catch (error) {
129
+ results.push({ success: false, id: String(file.id), filename: file.filename, error: error?.message });
130
+ }
131
+ progress.current++;
132
+ if (onProgress)
133
+ onProgress({ ...progress });
134
+ }
135
+ if (delayMs > 0)
136
+ await sleep(delayMs);
137
+ }
138
+ const summary = {
139
+ exportDate: new Date().toISOString(),
140
+ totalFiles: filtered.length,
141
+ successful: results.filter((r) => r.success).length,
142
+ failed: results.filter((r) => !r.success),
143
+ includesTrash: includeTrash,
144
+ since: since || null,
145
+ until: until || null,
146
+ };
147
+ if (archive) {
148
+ archive.append(JSON.stringify(summary, null, 2), { name: "export_summary.json" });
149
+ archive.finalize();
150
+ await new Promise((resolve, reject) => {
151
+ archiveStream.on("close", resolve);
152
+ archiveStream.on("error", reject);
153
+ });
154
+ }
155
+ else {
156
+ await fs.writeFile(path.join(outDir, "export_summary.json"), JSON.stringify(summary, null, 2), "utf8");
157
+ }
158
+ return {
159
+ ...summary,
160
+ outDir: zipPath ? null : outDir,
161
+ zipPath: zipPath || null,
162
+ };
163
+ }
164
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../src/export.ts"],"names":[],"mappings":"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"}
package/dist/output.js ADDED
@@ -0,0 +1,52 @@
1
+ function isObject(value) {
2
+ return !!value && typeof value === "object" && !Array.isArray(value);
3
+ }
4
+ export function toErrorCode(err) {
5
+ const status = err?.status;
6
+ if (status === 401 || status === 403)
7
+ return "AUTH_INVALID";
8
+ if (status === 404)
9
+ return "NOT_FOUND";
10
+ if (status === 429)
11
+ return "RATE_LIMITED";
12
+ if (typeof status === "number" && status >= 500)
13
+ return "UPSTREAM_5XX";
14
+ if (err?.name === "AbortError")
15
+ return "TIMEOUT";
16
+ return "UNKNOWN";
17
+ }
18
+ export function isRetryable(err) {
19
+ const code = toErrorCode(err);
20
+ return code === "RATE_LIMITED" || code === "UPSTREAM_5XX" || code === "TIMEOUT";
21
+ }
22
+ export function makeError(err, { code, message } = {}) {
23
+ const status = err?.status;
24
+ const errorData = err?.data;
25
+ const resolvedCode = code || toErrorCode(err);
26
+ const resolvedMessage = message || err?.message || "Request failed";
27
+ const base = {
28
+ code: resolvedCode,
29
+ message: resolvedMessage,
30
+ retryable: isRetryable(err),
31
+ };
32
+ if (typeof status === "number")
33
+ base.http = { status };
34
+ // Keep error details small and non-sensitive.
35
+ if (isObject(errorData)) {
36
+ const detail = errorData.detail || errorData.msg || errorData.message;
37
+ if (detail && String(detail) !== resolvedMessage)
38
+ base.detail = String(detail);
39
+ }
40
+ return base;
41
+ }
42
+ export function printJson(obj) {
43
+ // eslint-disable-next-line no-console
44
+ console.log(JSON.stringify(obj, null, 2));
45
+ }
46
+ export function ok(data, meta) {
47
+ return meta ? { ok: true, data, meta } : { ok: true, data };
48
+ }
49
+ export function fail(error, meta) {
50
+ return meta ? { ok: false, error, meta } : { ok: false, error };
51
+ }
52
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACvE,CAAC;AAUD,MAAM,UAAU,WAAW,CAAC,GAAQ;IAClC,MAAM,MAAM,GAAG,GAAG,EAAE,MAA4B,CAAC;IACjD,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,cAAc,CAAC;IAC5D,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,WAAW,CAAC;IACvC,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,cAAc,CAAC;IAC1C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG;QAAE,OAAO,cAAc,CAAC;IACvE,IAAI,GAAG,EAAE,IAAI,KAAK,YAAY;QAAE,OAAO,SAAS,CAAC;IACjD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAQ;IAClC,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,OAAO,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,SAAS,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,KAA0C,EAAE;IAC7F,MAAM,MAAM,GAAG,GAAG,EAAE,MAA4B,CAAC;IACjD,MAAM,SAAS,GAAG,GAAG,EAAE,IAAe,CAAC;IACvC,MAAM,YAAY,GAAG,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9C,MAAM,eAAe,GAAG,OAAO,IAAI,GAAG,EAAE,OAAO,IAAI,gBAAgB,CAAC;IAEpE,MAAM,IAAI,GAAa;QACrB,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,eAAe;QACxB,SAAS,EAAE,WAAW,CAAC,GAAG,CAAC;KAC5B,CAAC;IAEF,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,IAAI,CAAC,IAAI,GAAG,EAAE,MAAM,EAAE,CAAC;IAEvD,8CAA8C;IAC9C,IAAI,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC;QACtE,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,eAAe;YAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACjF,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAMD,MAAM,UAAU,SAAS,CAAC,GAAY;IACpC,sCAAsC;IACtC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,EAAE,CAAI,IAAO,EAAE,IAA8B;IAC3D,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,KAAe,EAAE,IAA8B;IAClE,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAClE,CAAC"}
@@ -0,0 +1,145 @@
1
+ import { readConfig } from "./config.js";
2
+ const BASE_URL = "https://api.plaud.ai";
3
+ function sleep(ms) {
4
+ return new Promise((resolve) => setTimeout(resolve, ms));
5
+ }
6
+ function cleanToken(token) {
7
+ return String(token || "")
8
+ .trim()
9
+ .replace(/^bearer\s+/i, "");
10
+ }
11
+ export async function resolveAuthToken() {
12
+ if (process.env.PLAUD_AUTH_TOKEN)
13
+ return cleanToken(process.env.PLAUD_AUTH_TOKEN);
14
+ const config = await readConfig();
15
+ if (config?.authToken)
16
+ return cleanToken(config.authToken);
17
+ return "";
18
+ }
19
+ async function readJsonOrThrow(response) {
20
+ let data;
21
+ try {
22
+ data = await response.json();
23
+ }
24
+ catch {
25
+ data = null;
26
+ }
27
+ if (response.ok)
28
+ return data;
29
+ const detail = (data && typeof data === "object" && (data.detail || data.msg || data.message)) || "";
30
+ const message = detail ? String(detail) : `HTTP ${response.status} ${response.statusText}`;
31
+ const error = new Error(message);
32
+ error.status = response.status;
33
+ error.data = data;
34
+ throw error;
35
+ }
36
+ export async function plaudRequest({ token, endpoint, method = "GET", body, timeoutMs = 30_000, retries = 4, }) {
37
+ const url = `${BASE_URL}${endpoint}`;
38
+ const headers = {
39
+ accept: "application/json, text/plain, */*",
40
+ "accept-language": "en-US,en;q=0.9",
41
+ "app-platform": "web",
42
+ authorization: `bearer ${cleanToken(token)}`,
43
+ "content-type": "application/json",
44
+ dnt: "1",
45
+ "edit-from": "web",
46
+ origin: "https://app.plaud.ai",
47
+ referer: "https://app.plaud.ai/",
48
+ };
49
+ for (let attempt = 0; attempt <= retries; attempt++) {
50
+ const controller = new AbortController();
51
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
52
+ try {
53
+ const response = await fetch(url, {
54
+ method,
55
+ headers,
56
+ body: body === undefined ? undefined : JSON.stringify(body),
57
+ signal: controller.signal,
58
+ });
59
+ return await readJsonOrThrow(response);
60
+ }
61
+ catch (error) {
62
+ const isLast = attempt === retries;
63
+ const status = error?.status;
64
+ const transient = error?.name === "AbortError" ||
65
+ status === 429 ||
66
+ (typeof status === "number" && status >= 500);
67
+ if (isLast || !transient)
68
+ throw error;
69
+ const backoffMs = Math.min(10_000, 500 * 2 ** attempt);
70
+ await sleep(backoffMs);
71
+ }
72
+ finally {
73
+ clearTimeout(timeout);
74
+ }
75
+ }
76
+ // unreachable
77
+ throw new Error("Request failed");
78
+ }
79
+ export async function getMe({ token }) {
80
+ return await plaudRequest({ token, endpoint: "/user/me", timeoutMs: 15_000, retries: 1 });
81
+ }
82
+ export async function getRecordingTempUrls({ token, id }) {
83
+ if (!id)
84
+ throw new Error("Missing recording id");
85
+ return await plaudRequest({ token, endpoint: `/file/temp-url/${encodeURIComponent(String(id))}` });
86
+ }
87
+ function parseFileListResponse(listResponse) {
88
+ if (!listResponse || typeof listResponse !== "object")
89
+ return [];
90
+ if (listResponse.detail && String(listResponse.detail).toLowerCase().includes("token")) {
91
+ throw new Error("Auth token expired/invalid. Re-run `plaud auth set`.");
92
+ }
93
+ if (listResponse.status !== undefined && listResponse.status !== 0) {
94
+ throw new Error(listResponse.msg || listResponse.message || "API error");
95
+ }
96
+ const candidates = [
97
+ listResponse.data_file_list,
98
+ listResponse.files,
99
+ listResponse.data,
100
+ listResponse.dataFileList,
101
+ listResponse.list,
102
+ listResponse.file_list,
103
+ listResponse.items,
104
+ listResponse.records,
105
+ ];
106
+ for (const c of candidates) {
107
+ if (Array.isArray(c))
108
+ return c;
109
+ }
110
+ return [];
111
+ }
112
+ export async function listRecordings({ token, includeTrash = false, pageSize = 200, max = Infinity, }) {
113
+ const isTrash = includeTrash ? 2 : 0;
114
+ const recordings = [];
115
+ let skip = 0;
116
+ while (recordings.length < max) {
117
+ const limit = Math.min(pageSize, max - recordings.length);
118
+ const res = await plaudRequest({
119
+ token,
120
+ endpoint: `/file/simple/web?skip=${skip}&limit=${limit}&is_trash=${isTrash}&sort_by=start_time&is_desc=true`,
121
+ });
122
+ const batch = parseFileListResponse(res);
123
+ if (batch.length === 0)
124
+ break;
125
+ recordings.push(...batch);
126
+ skip += batch.length;
127
+ if (batch.length < limit)
128
+ break;
129
+ }
130
+ return recordings;
131
+ }
132
+ export async function getRecordingDetailsBatch({ token, ids }) {
133
+ if (!Array.isArray(ids) || ids.length === 0)
134
+ return [];
135
+ const res = await plaudRequest({
136
+ token,
137
+ endpoint: "/file/list?support_mul_summ=true",
138
+ method: "POST",
139
+ body: ids,
140
+ });
141
+ if (res?.status === 0 && Array.isArray(res?.data_file_list))
142
+ return res.data_file_list;
143
+ return [];
144
+ }
145
+ //# sourceMappingURL=plaud-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plaud-api.js","sourceRoot":"","sources":["../src/plaud-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ function formatTime(milliseconds) {
2
+ const totalSeconds = Math.floor(Number(milliseconds || 0) / 1000);
3
+ const hours = Math.floor(totalSeconds / 3600);
4
+ const minutes = Math.floor((totalSeconds % 3600) / 60);
5
+ const seconds = totalSeconds % 60;
6
+ if (hours > 0) {
7
+ return `${hours}:${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
8
+ }
9
+ return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
10
+ }
11
+ function formatDate(timestamp) {
12
+ if (!timestamp)
13
+ return "";
14
+ const date = new Date(timestamp);
15
+ if (Number.isNaN(date.getTime()))
16
+ return "";
17
+ const year = date.getFullYear();
18
+ const month = String(date.getMonth() + 1).padStart(2, "0");
19
+ const day = String(date.getDate()).padStart(2, "0");
20
+ return `${year}-${month}-${day}`;
21
+ }
22
+ export function sanitizeFilename(filename) {
23
+ return String(filename || "untitled")
24
+ .replace(/[<>:"/\\|?*]/g, "-")
25
+ .replace(/\s+/g, "_")
26
+ .slice(0, 200);
27
+ }
28
+ export function getFilenameWithDate(baseFilename, file, details) {
29
+ const timestamp = details?.start_time || file?.start_time || details?.edit_time || file?.edit_time;
30
+ const datePrefix = formatDate(timestamp);
31
+ const sanitized = sanitizeFilename(baseFilename || file?.id || "untitled");
32
+ return datePrefix ? `${datePrefix}_${sanitized}` : sanitized;
33
+ }
34
+ export function formatTranscript(segments) {
35
+ if (!Array.isArray(segments))
36
+ return "";
37
+ return segments
38
+ .map((segment) => {
39
+ const time = formatTime(segment.start_time);
40
+ const speaker = segment.speaker || "Speaker";
41
+ const content = segment.content || "";
42
+ return `[${time}] ${speaker}: ${content}`;
43
+ })
44
+ .join("\n\n");
45
+ }
46
+ //# sourceMappingURL=recordings-format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recordings-format.js","sourceRoot":"","sources":["../src/recordings-format.ts"],"names":[],"mappings":"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"}