@amaster.ai/pi-attachments 0.1.2-beta.10 → 0.1.2-beta.11
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/dist/classify.d.ts +18 -7
- package/dist/classify.d.ts.map +1 -1
- package/dist/classify.js +172 -93
- package/dist/classify.js.map +1 -1
- package/dist/extension.d.ts +3 -0
- package/dist/extension.d.ts.map +1 -0
- package/dist/extension.js +150 -0
- package/dist/extension.js.map +1 -0
- package/dist/index.d.ts +2 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -5
- package/dist/index.js.map +1 -1
- package/package.json +29 -6
- package/README.md +0 -37
- package/dist/diagnostics.d.ts +0 -8
- package/dist/diagnostics.d.ts.map +0 -1
- package/dist/diagnostics.js +0 -30
- package/dist/diagnostics.js.map +0 -1
- package/dist/http.d.ts +0 -10
- package/dist/http.d.ts.map +0 -1
- package/dist/http.js +0 -44
- package/dist/http.js.map +0 -1
- package/dist/local-store.d.ts +0 -20
- package/dist/local-store.d.ts.map +0 -1
- package/dist/local-store.js +0 -121
- package/dist/local-store.js.map +0 -1
- package/dist/multipart.d.ts +0 -9
- package/dist/multipart.d.ts.map +0 -1
- package/dist/multipart.js +0 -48
- package/dist/multipart.js.map +0 -1
- package/dist/normalize.d.ts +0 -7
- package/dist/normalize.d.ts.map +0 -1
- package/dist/normalize.js +0 -83
- package/dist/normalize.js.map +0 -1
- package/dist/parser.d.ts +0 -12
- package/dist/parser.d.ts.map +0 -1
- package/dist/parser.js +0 -168
- package/dist/parser.js.map +0 -1
- package/dist/prompt.d.ts +0 -10
- package/dist/prompt.d.ts.map +0 -1
- package/dist/prompt.js +0 -38
- package/dist/prompt.js.map +0 -1
- package/dist/remote-fetch.d.ts +0 -10
- package/dist/remote-fetch.d.ts.map +0 -1
- package/dist/remote-fetch.js +0 -35
- package/dist/remote-fetch.js.map +0 -1
- package/dist/routes.d.ts +0 -14
- package/dist/routes.d.ts.map +0 -1
- package/dist/routes.js +0 -91
- package/dist/routes.js.map +0 -1
- package/dist/service.d.ts +0 -9
- package/dist/service.d.ts.map +0 -1
- package/dist/service.js +0 -140
- package/dist/service.js.map +0 -1
- package/dist/types.d.ts +0 -85
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/upload-proxy.d.ts +0 -19
- package/dist/upload-proxy.d.ts.map +0 -1
- package/dist/upload-proxy.js +0 -105
- package/dist/upload-proxy.js.map +0 -1
package/README.md
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# @amaster.ai/pi-attachments
|
|
2
|
-
|
|
3
|
-
Attachment preparation utilities for Pi Agent runtimes.
|
|
4
|
-
|
|
5
|
-
This package normalizes chat attachment inputs, stores or fetches uploaded files,
|
|
6
|
-
extracts model-readable text from common document formats, and produces
|
|
7
|
-
model-visible image payloads for supported bitmap images.
|
|
8
|
-
|
|
9
|
-
## Design
|
|
10
|
-
|
|
11
|
-
- The core package is transport-agnostic. Local uploads and proxied remote
|
|
12
|
-
uploads are both represented as attachment sources.
|
|
13
|
-
- Platform authentication is injected through `AttachmentUploadAuth`; the
|
|
14
|
-
package does not depend on a specific auth provider.
|
|
15
|
-
- Provider-specific image content is represented with a small structural type
|
|
16
|
-
so callers can adapt it to their own model SDK.
|
|
17
|
-
- File parsing is best-effort. Text, SVG, CSV/TSV, PPTX, and legacy PPT fallbacks
|
|
18
|
-
are handled locally. Other document formats can use the LiteParse parser when
|
|
19
|
-
enabled.
|
|
20
|
-
|
|
21
|
-
## Supported Inputs
|
|
22
|
-
|
|
23
|
-
- Inline text: `txt`, `md`, `json`, `html`, `xml`, `svg`, `yaml`, source files,
|
|
24
|
-
logs, CSV, and TSV.
|
|
25
|
-
- Bitmap images: `jpeg`, `png`, `gif`, and `webp`.
|
|
26
|
-
- Documents: `pdf`, `doc/docx`, `xls/xlsx/xlsm`, `ppt/pptx`, `odt`, `ods`,
|
|
27
|
-
`odp`, and `rtf` when parsing is enabled.
|
|
28
|
-
|
|
29
|
-
## Public API
|
|
30
|
-
|
|
31
|
-
- `createAttachmentService(config)`
|
|
32
|
-
- `handleAttachmentRoutes(input)`
|
|
33
|
-
- `normalizeAttachments(value, maxCount)`
|
|
34
|
-
- `renderAttachmentPrompt(message, bundle)`
|
|
35
|
-
- `checkAttachmentHostDependencies()`
|
|
36
|
-
|
|
37
|
-
The package is ESM-only.
|
package/dist/diagnostics.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export type AttachmentDependencyCheck = {
|
|
2
|
-
name: 'libreoffice' | 'imagemagick' | 'ghostscript' | 'tesseract' | 'poppler';
|
|
3
|
-
command: string;
|
|
4
|
-
installed: boolean;
|
|
5
|
-
version?: string;
|
|
6
|
-
};
|
|
7
|
-
export declare function checkAttachmentHostDependencies(): Promise<AttachmentDependencyCheck[]>;
|
|
8
|
-
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,aAAa,GAAG,aAAa,GAAG,aAAa,GAAG,WAAW,GAAG,SAAS,CAAC;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAsB,+BAA+B,IAAI,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAmB5F"}
|
package/dist/diagnostics.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process';
|
|
2
|
-
export async function checkAttachmentHostDependencies() {
|
|
3
|
-
const checks = [
|
|
4
|
-
{ name: 'libreoffice', command: 'soffice', args: ['--version'] },
|
|
5
|
-
{ name: 'imagemagick', command: 'magick', args: ['-version'] },
|
|
6
|
-
{ name: 'ghostscript', command: 'gs', args: ['--version'] },
|
|
7
|
-
{ name: 'tesseract', command: 'tesseract', args: ['--version'] },
|
|
8
|
-
{ name: 'poppler', command: 'pdftotext', args: ['-v'] },
|
|
9
|
-
];
|
|
10
|
-
return Promise.all(checks.map(async (check) => {
|
|
11
|
-
const result = await run(check.command, check.args);
|
|
12
|
-
return {
|
|
13
|
-
name: check.name,
|
|
14
|
-
command: check.command,
|
|
15
|
-
installed: result.code === 0,
|
|
16
|
-
...(result.output ? { version: result.output.split(/\r?\n/)[0] } : {}),
|
|
17
|
-
};
|
|
18
|
-
}));
|
|
19
|
-
}
|
|
20
|
-
function run(command, args) {
|
|
21
|
-
return new Promise((resolve) => {
|
|
22
|
-
const child = spawn(command, args, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
23
|
-
const chunks = [];
|
|
24
|
-
child.stdout.on('data', (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
|
|
25
|
-
child.stderr.on('data', (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
|
|
26
|
-
child.on('error', () => resolve({ code: -1, output: '' }));
|
|
27
|
-
child.on('close', (code) => resolve({ code, output: Buffer.concat(chunks).toString('utf8').trim() }));
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=diagnostics.js.map
|
package/dist/diagnostics.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAS3C,MAAM,CAAC,KAAK,UAAU,+BAA+B;IACnD,MAAM,MAAM,GAAG;QACb,EAAE,IAAI,EAAE,aAAsB,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE;QACzE,EAAE,IAAI,EAAE,aAAsB,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE;QACvE,EAAE,IAAI,EAAE,aAAsB,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE;QACpE,EAAE,IAAI,EAAE,WAAoB,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE;QACzE,EAAE,IAAI,EAAE,SAAkB,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE;KACjE,CAAC;IACF,OAAO,OAAO,CAAC,GAAG,CAChB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACzB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACpD,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,SAAS,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC;YAC5B,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvE,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,SAAS,GAAG,CAAC,OAAe,EAAE,IAAc;IAC1C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1E,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAChC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CACjE,CAAC;QACF,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAChC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CACjE,CAAC;QACF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC3D,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CACzB,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACzE,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/http.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
export declare class AttachmentHttpError extends Error {
|
|
3
|
-
readonly statusCode: number;
|
|
4
|
-
readonly code: string;
|
|
5
|
-
constructor(statusCode: number, code: string, message: string);
|
|
6
|
-
}
|
|
7
|
-
export declare function readRequestBody(request: IncomingMessage, maxBytes: number): Promise<Buffer>;
|
|
8
|
-
export declare function writeJson(response: ServerResponse, statusCode: number, body: unknown): void;
|
|
9
|
-
export declare function getHeader(request: IncomingMessage, name: string): string | undefined;
|
|
10
|
-
//# sourceMappingURL=http.d.ts.map
|
package/dist/http.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,qBAAa,mBAAoB,SAAQ,KAAK;IAE1C,QAAQ,CAAC,UAAU,EAAE,MAAM;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM;gBADZ,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM;CAKlB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBjG;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAS3F;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKpF"}
|
package/dist/http.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
export class AttachmentHttpError extends Error {
|
|
2
|
-
statusCode;
|
|
3
|
-
code;
|
|
4
|
-
constructor(statusCode, code, message) {
|
|
5
|
-
super(message);
|
|
6
|
-
this.statusCode = statusCode;
|
|
7
|
-
this.code = code;
|
|
8
|
-
this.name = 'AttachmentHttpError';
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
export async function readRequestBody(request, maxBytes) {
|
|
12
|
-
const contentLength = Number(request.headers['content-length']);
|
|
13
|
-
if (Number.isFinite(contentLength) && contentLength > maxBytes) {
|
|
14
|
-
throw new AttachmentHttpError(413, 'request_body_too_large', `request body exceeds ${maxBytes} bytes`);
|
|
15
|
-
}
|
|
16
|
-
const chunks = [];
|
|
17
|
-
let totalBytes = 0;
|
|
18
|
-
for await (const chunk of request) {
|
|
19
|
-
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
20
|
-
totalBytes += buffer.length;
|
|
21
|
-
if (totalBytes > maxBytes) {
|
|
22
|
-
throw new AttachmentHttpError(413, 'request_body_too_large', `request body exceeds ${maxBytes} bytes`);
|
|
23
|
-
}
|
|
24
|
-
chunks.push(buffer);
|
|
25
|
-
}
|
|
26
|
-
return Buffer.concat(chunks);
|
|
27
|
-
}
|
|
28
|
-
export function writeJson(response, statusCode, body) {
|
|
29
|
-
if (response.headersSent) {
|
|
30
|
-
if (!response.writableEnded) {
|
|
31
|
-
response.end();
|
|
32
|
-
}
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
response.writeHead(statusCode, { 'content-type': 'application/json; charset=utf-8' });
|
|
36
|
-
response.end(`${JSON.stringify(body)}\n`);
|
|
37
|
-
}
|
|
38
|
-
export function getHeader(request, name) {
|
|
39
|
-
const value = request.headers[name.toLowerCase()];
|
|
40
|
-
const candidate = Array.isArray(value) ? value[0] : value;
|
|
41
|
-
const trimmed = candidate?.trim();
|
|
42
|
-
return trimmed ? trimmed : undefined;
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAEjC;IACA;IAFX,YACW,UAAkB,EAClB,IAAY,EACrB,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAJN,eAAU,GAAV,UAAU,CAAQ;QAClB,SAAI,GAAJ,IAAI,CAAQ;QAIrB,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAwB,EAAE,QAAgB;IAC9E,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAChE,IAAI,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,aAAa,GAAG,QAAQ,EAAE,CAAC;QAC/D,MAAM,IAAI,mBAAmB,CAC3B,GAAG,EACH,wBAAwB,EACxB,wBAAwB,QAAQ,QAAQ,CACzC,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnE,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,UAAU,GAAG,QAAQ,EAAE,CAAC;YAC1B,MAAM,IAAI,mBAAmB,CAC3B,GAAG,EACH,wBAAwB,EACxB,wBAAwB,QAAQ,QAAQ,CACzC,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAwB,EAAE,UAAkB,EAAE,IAAa;IACnF,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC5B,QAAQ,CAAC,GAAG,EAAE,CAAC;QACjB,CAAC;QACD,OAAO;IACT,CAAC;IACD,QAAQ,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,cAAc,EAAE,iCAAiC,EAAE,CAAC,CAAC;IACtF,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAwB,EAAE,IAAY;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC1D,MAAM,OAAO,GAAG,SAAS,EAAE,IAAI,EAAE,CAAC;IAClC,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACvC,CAAC"}
|
package/dist/local-store.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { StoredAttachmentRecord } from './types.js';
|
|
2
|
-
export declare class LocalAttachmentStore {
|
|
3
|
-
private readonly rootDir;
|
|
4
|
-
constructor(rootDir: string);
|
|
5
|
-
putFile(input: {
|
|
6
|
-
sourcePath: string;
|
|
7
|
-
name?: string;
|
|
8
|
-
mimeType?: string;
|
|
9
|
-
sessionId?: string;
|
|
10
|
-
}): Promise<StoredAttachmentRecord>;
|
|
11
|
-
putBuffer(input: {
|
|
12
|
-
data: Buffer;
|
|
13
|
-
name: string;
|
|
14
|
-
mimeType?: string;
|
|
15
|
-
sessionId?: string;
|
|
16
|
-
}): Promise<StoredAttachmentRecord>;
|
|
17
|
-
readRecord(attachmentId: string): Promise<StoredAttachmentRecord>;
|
|
18
|
-
private attachmentDir;
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=local-store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-store.d.ts","sourceRoot":"","sources":["../src/local-store.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,MAAM;IAEtC,OAAO,CAAC,KAAK,EAAE;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAuB7B,SAAS,CAAC,KAAK,EAAE;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAkB7B,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAgBvE,OAAO,CAAC,aAAa;CAKtB"}
|
package/dist/local-store.js
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
-
import { copyFile, mkdir, readFile, stat, writeFile } from 'node:fs/promises';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { mimeTypeFromFileName } from './classify.js';
|
|
6
|
-
export class LocalAttachmentStore {
|
|
7
|
-
rootDir;
|
|
8
|
-
constructor(rootDir) {
|
|
9
|
-
this.rootDir = rootDir;
|
|
10
|
-
}
|
|
11
|
-
async putFile(input) {
|
|
12
|
-
const sourcePath = fileURLToPathIfNeeded(input.sourcePath);
|
|
13
|
-
const sourceStat = await stat(sourcePath);
|
|
14
|
-
if (!sourceStat.isFile()) {
|
|
15
|
-
throw new Error(`attachment source is not a file: ${input.sourcePath}`);
|
|
16
|
-
}
|
|
17
|
-
const name = sanitizeFileName(input.name ?? path.basename(sourcePath));
|
|
18
|
-
const attachmentId = randomUUID();
|
|
19
|
-
const dir = this.attachmentDir(input.sessionId, attachmentId);
|
|
20
|
-
await mkdir(dir, { recursive: true });
|
|
21
|
-
const targetPath = path.join(dir, name);
|
|
22
|
-
await copyFile(sourcePath, targetPath);
|
|
23
|
-
const record = createRecord({
|
|
24
|
-
attachmentId,
|
|
25
|
-
name,
|
|
26
|
-
size: sourceStat.size,
|
|
27
|
-
path: targetPath,
|
|
28
|
-
...optionalMimeType(input.mimeType ?? mimeTypeFromFileName(name)),
|
|
29
|
-
});
|
|
30
|
-
await writeRecord(dir, record);
|
|
31
|
-
return record;
|
|
32
|
-
}
|
|
33
|
-
async putBuffer(input) {
|
|
34
|
-
const name = sanitizeFileName(input.name);
|
|
35
|
-
const attachmentId = randomUUID();
|
|
36
|
-
const dir = this.attachmentDir(input.sessionId, attachmentId);
|
|
37
|
-
await mkdir(dir, { recursive: true });
|
|
38
|
-
const targetPath = path.join(dir, name);
|
|
39
|
-
await writeFile(targetPath, input.data);
|
|
40
|
-
const record = createRecord({
|
|
41
|
-
attachmentId,
|
|
42
|
-
name,
|
|
43
|
-
size: input.data.byteLength,
|
|
44
|
-
path: targetPath,
|
|
45
|
-
...optionalMimeType(input.mimeType ?? mimeTypeFromFileName(name)),
|
|
46
|
-
});
|
|
47
|
-
await writeRecord(dir, record);
|
|
48
|
-
return record;
|
|
49
|
-
}
|
|
50
|
-
async readRecord(attachmentId) {
|
|
51
|
-
const safeId = sanitizeId(attachmentId);
|
|
52
|
-
const candidates = await findRecordCandidates(this.rootDir, safeId);
|
|
53
|
-
for (const candidate of candidates) {
|
|
54
|
-
try {
|
|
55
|
-
const parsed = JSON.parse(await readFile(candidate, 'utf8'));
|
|
56
|
-
if (parsed.attachmentId === attachmentId) {
|
|
57
|
-
return parsed;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
catch {
|
|
61
|
-
// Keep looking for another candidate.
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
throw new Error(`stored attachment not found: ${attachmentId}`);
|
|
65
|
-
}
|
|
66
|
-
attachmentDir(sessionId, attachmentId) {
|
|
67
|
-
const sessionPart = sanitizeId(sessionId ?? 'global');
|
|
68
|
-
const hash = createHash('sha256').update(attachmentId).digest('hex').slice(0, 8);
|
|
69
|
-
return path.join(this.rootDir, sessionPart, `${hash}-${sanitizeId(attachmentId)}`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
function createRecord(input) {
|
|
73
|
-
return {
|
|
74
|
-
attachmentId: input.attachmentId,
|
|
75
|
-
name: input.name,
|
|
76
|
-
...(input.mimeType ? { mimeType: input.mimeType } : {}),
|
|
77
|
-
size: input.size,
|
|
78
|
-
path: input.path,
|
|
79
|
-
createdAt: new Date().toISOString(),
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
async function writeRecord(dir, record) {
|
|
83
|
-
await writeFile(path.join(dir, 'attachment.json'), `${JSON.stringify(record, null, 2)}\n`, 'utf8');
|
|
84
|
-
}
|
|
85
|
-
async function findRecordCandidates(rootDir, attachmentId) {
|
|
86
|
-
const { readdir } = await import('node:fs/promises');
|
|
87
|
-
const result = [];
|
|
88
|
-
try {
|
|
89
|
-
for (const sessionEntry of await readdir(rootDir, { withFileTypes: true })) {
|
|
90
|
-
if (!sessionEntry.isDirectory())
|
|
91
|
-
continue;
|
|
92
|
-
const sessionDir = path.join(rootDir, sessionEntry.name);
|
|
93
|
-
for (const attachmentEntry of await readdir(sessionDir, { withFileTypes: true })) {
|
|
94
|
-
if (attachmentEntry.isDirectory() && attachmentEntry.name.endsWith(`-${attachmentId}`)) {
|
|
95
|
-
result.push(path.join(sessionDir, attachmentEntry.name, 'attachment.json'));
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
return [];
|
|
102
|
-
}
|
|
103
|
-
return result;
|
|
104
|
-
}
|
|
105
|
-
function sanitizeFileName(value) {
|
|
106
|
-
const base = path
|
|
107
|
-
.basename(value)
|
|
108
|
-
.replace(/[^\w .@()+=[\]-]/g, '_')
|
|
109
|
-
.trim();
|
|
110
|
-
return base || 'attachment';
|
|
111
|
-
}
|
|
112
|
-
function optionalMimeType(mimeType) {
|
|
113
|
-
return mimeType ? { mimeType } : {};
|
|
114
|
-
}
|
|
115
|
-
function sanitizeId(value) {
|
|
116
|
-
return value.replace(/[^a-zA-Z0-9_.-]/g, '_').slice(0, 160) || 'attachment';
|
|
117
|
-
}
|
|
118
|
-
function fileURLToPathIfNeeded(value) {
|
|
119
|
-
return value.startsWith('file://') ? fileURLToPath(value) : value;
|
|
120
|
-
}
|
|
121
|
-
//# sourceMappingURL=local-store.js.map
|
package/dist/local-store.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-store.js","sourceRoot":"","sources":["../src/local-store.ts"],"names":[],"mappings":"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"}
|
package/dist/multipart.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export type MultipartFile = {
|
|
2
|
-
fieldName: string;
|
|
3
|
-
fileName: string;
|
|
4
|
-
contentType?: string;
|
|
5
|
-
data: Buffer;
|
|
6
|
-
};
|
|
7
|
-
export declare function parseMultipartBoundary(contentType: string | string[] | undefined): string | undefined;
|
|
8
|
-
export declare function parseMultipartFiles(body: Buffer, boundary: string): MultipartFile[];
|
|
9
|
-
//# sourceMappingURL=multipart.d.ts.map
|
package/dist/multipart.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multipart.d.ts","sourceRoot":"","sources":["../src/multipart.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GACzC,MAAM,GAAG,SAAS,CAIpB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE,CA8BnF"}
|
package/dist/multipart.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
export function parseMultipartBoundary(contentType) {
|
|
2
|
-
const value = Array.isArray(contentType) ? contentType[0] : contentType;
|
|
3
|
-
const match = value?.match(/(?:^|;)\s*boundary=(?:"([^"]+)"|([^;]+))/i);
|
|
4
|
-
return match?.[1] ?? match?.[2]?.trim();
|
|
5
|
-
}
|
|
6
|
-
export function parseMultipartFiles(body, boundary) {
|
|
7
|
-
const marker = `--${boundary}`;
|
|
8
|
-
const text = body.toString('binary');
|
|
9
|
-
const parts = text.split(marker).slice(1, -1);
|
|
10
|
-
const files = [];
|
|
11
|
-
for (const part of parts) {
|
|
12
|
-
const trimmed = part.replace(/^\r?\n/, '');
|
|
13
|
-
const separator = trimmed.indexOf('\r\n\r\n');
|
|
14
|
-
if (separator < 0) {
|
|
15
|
-
continue;
|
|
16
|
-
}
|
|
17
|
-
const rawHeaders = trimmed.slice(0, separator);
|
|
18
|
-
const contentStart = separator + 4;
|
|
19
|
-
const rawContent = trimmed.slice(contentStart).replace(/\r\n$/, '');
|
|
20
|
-
const headers = parsePartHeaders(rawHeaders);
|
|
21
|
-
const disposition = headers.get('content-disposition') ?? '';
|
|
22
|
-
const name = disposition.match(/name="([^"]+)"/)?.[1];
|
|
23
|
-
const fileName = disposition.match(/filename="([^"]*)"/)?.[1];
|
|
24
|
-
if (!name || !fileName) {
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
const contentType = headers.get('content-type');
|
|
28
|
-
files.push({
|
|
29
|
-
fieldName: name,
|
|
30
|
-
fileName,
|
|
31
|
-
...(contentType ? { contentType } : {}),
|
|
32
|
-
data: Buffer.from(rawContent, 'binary'),
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
return files;
|
|
36
|
-
}
|
|
37
|
-
function parsePartHeaders(value) {
|
|
38
|
-
const headers = new Map();
|
|
39
|
-
for (const line of value.split(/\r?\n/)) {
|
|
40
|
-
const separator = line.indexOf(':');
|
|
41
|
-
if (separator <= 0) {
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
headers.set(line.slice(0, separator).trim().toLowerCase(), line.slice(separator + 1).trim());
|
|
45
|
-
}
|
|
46
|
-
return headers;
|
|
47
|
-
}
|
|
48
|
-
//# sourceMappingURL=multipart.js.map
|
package/dist/multipart.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multipart.js","sourceRoot":"","sources":["../src/multipart.ts"],"names":[],"mappings":"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"}
|
package/dist/normalize.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { NormalizedAttachment } from './types.js';
|
|
2
|
-
export declare class AttachmentValidationError extends Error {
|
|
3
|
-
readonly statusCode: number;
|
|
4
|
-
constructor(message: string, statusCode?: number);
|
|
5
|
-
}
|
|
6
|
-
export declare function normalizeAttachments(value: unknown, maxCount: number): NormalizedAttachment[];
|
|
7
|
-
//# sourceMappingURL=normalize.d.ts.map
|
package/dist/normalize.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyC,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE9F,qBAAa,yBAA0B,SAAQ,KAAK;IAGhD,QAAQ,CAAC,UAAU;gBADnB,OAAO,EAAE,MAAM,EACN,UAAU,SAAM;CAK5B;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAW7F"}
|
package/dist/normalize.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
export class AttachmentValidationError extends Error {
|
|
2
|
-
statusCode;
|
|
3
|
-
constructor(message, statusCode = 400) {
|
|
4
|
-
super(message);
|
|
5
|
-
this.statusCode = statusCode;
|
|
6
|
-
this.name = 'AttachmentValidationError';
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
export function normalizeAttachments(value, maxCount) {
|
|
10
|
-
if (value === undefined) {
|
|
11
|
-
return [];
|
|
12
|
-
}
|
|
13
|
-
if (!Array.isArray(value)) {
|
|
14
|
-
throw new AttachmentValidationError('attachments must be an array');
|
|
15
|
-
}
|
|
16
|
-
if (value.length > maxCount) {
|
|
17
|
-
throw new AttachmentValidationError(`attachments must include at most ${maxCount} files`);
|
|
18
|
-
}
|
|
19
|
-
return value.map((raw, index) => normalizeAttachment(raw, index));
|
|
20
|
-
}
|
|
21
|
-
function normalizeAttachment(value, index) {
|
|
22
|
-
if (!value || typeof value !== 'object') {
|
|
23
|
-
throw new AttachmentValidationError(`attachment ${index + 1} must be an object`);
|
|
24
|
-
}
|
|
25
|
-
const candidate = value;
|
|
26
|
-
const id = trimToUndefined(candidate.id);
|
|
27
|
-
const name = trimToUndefined(candidate.name);
|
|
28
|
-
if (!id) {
|
|
29
|
-
throw new AttachmentValidationError(`attachment ${index + 1} id is required`);
|
|
30
|
-
}
|
|
31
|
-
if (!name) {
|
|
32
|
-
throw new AttachmentValidationError(`attachment ${index + 1} name is required`);
|
|
33
|
-
}
|
|
34
|
-
const source = normalizeSource(candidate.source, index);
|
|
35
|
-
const mimeType = trimToUndefined(candidate.mimeType);
|
|
36
|
-
const size = typeof candidate.size === 'number' && Number.isFinite(candidate.size)
|
|
37
|
-
? Math.max(0, Math.floor(candidate.size))
|
|
38
|
-
: undefined;
|
|
39
|
-
return {
|
|
40
|
-
id,
|
|
41
|
-
name,
|
|
42
|
-
...(mimeType ? { mimeType } : {}),
|
|
43
|
-
...(size !== undefined ? { size } : {}),
|
|
44
|
-
source,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
function normalizeSource(value, index) {
|
|
48
|
-
if (!value || typeof value !== 'object') {
|
|
49
|
-
throw new AttachmentValidationError(`attachment ${index + 1} source is required`);
|
|
50
|
-
}
|
|
51
|
-
const source = value;
|
|
52
|
-
if (source.kind === 'inlineText') {
|
|
53
|
-
if (typeof source.text !== 'string') {
|
|
54
|
-
throw new AttachmentValidationError(`attachment ${index + 1} inline text is required`);
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
kind: 'inlineText',
|
|
58
|
-
text: source.text,
|
|
59
|
-
...(typeof source.truncated === 'boolean' ? { truncated: source.truncated } : {}),
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
if (source.kind === 'remoteObject') {
|
|
63
|
-
const url = trimToUndefined(typeof source.url === 'string' ? source.url : undefined);
|
|
64
|
-
if (!url) {
|
|
65
|
-
throw new AttachmentValidationError(`attachment ${index + 1} remote url is required`);
|
|
66
|
-
}
|
|
67
|
-
const key = trimToUndefined(typeof source.key === 'string' ? source.key : undefined);
|
|
68
|
-
return { kind: 'remoteObject', url, ...(key ? { key } : {}) };
|
|
69
|
-
}
|
|
70
|
-
if (source.kind === 'storedFile') {
|
|
71
|
-
const attachmentId = trimToUndefined(typeof source.attachmentId === 'string' ? source.attachmentId : undefined);
|
|
72
|
-
if (!attachmentId) {
|
|
73
|
-
throw new AttachmentValidationError(`attachment ${index + 1} stored attachment id is required`);
|
|
74
|
-
}
|
|
75
|
-
return { kind: 'storedFile', attachmentId };
|
|
76
|
-
}
|
|
77
|
-
throw new AttachmentValidationError(`attachment ${index + 1} source kind is invalid`);
|
|
78
|
-
}
|
|
79
|
-
function trimToUndefined(value) {
|
|
80
|
-
const trimmed = value?.trim();
|
|
81
|
-
return trimmed ? trimmed : undefined;
|
|
82
|
-
}
|
|
83
|
-
//# sourceMappingURL=normalize.js.map
|
package/dist/normalize.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAGvC;IAFX,YACE,OAAe,EACN,aAAa,GAAG;QAEzB,KAAK,CAAC,OAAO,CAAC,CAAC;QAFN,eAAU,GAAV,UAAU,CAAM;QAGzB,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;IAC1C,CAAC;CACF;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAc,EAAE,QAAgB;IACnE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,yBAAyB,CAAC,8BAA8B,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC5B,MAAM,IAAI,yBAAyB,CAAC,oCAAoC,QAAQ,QAAQ,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAc,EAAE,KAAa;IACxD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,IAAI,yBAAyB,CAAC,cAAc,KAAK,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,SAAS,GAAG,KAAqC,CAAC;IACxD,MAAM,EAAE,GAAG,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,MAAM,IAAI,yBAAyB,CAAC,cAAc,KAAK,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,yBAAyB,CAAC,cAAc,KAAK,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,MAAM,GAAG,eAAe,CAAE,SAAkC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAClF,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACrD,MAAM,IAAI,GACR,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC;QACnE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC,CAAC,SAAS,CAAC;IAChB,OAAO;QACL,EAAE;QACF,IAAI;QACJ,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,MAAM;KACP,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAc,EAAE,KAAa;IACpD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,IAAI,yBAAyB,CAAC,cAAc,KAAK,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACpF,CAAC;IACD,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QACjC,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpC,MAAM,IAAI,yBAAyB,CAAC,cAAc,KAAK,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACzF,CAAC;QACD,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,GAAG,CAAC,OAAO,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClF,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACrF,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,yBAAyB,CAAC,cAAc,KAAK,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACxF,CAAC;QACD,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACrF,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAChE,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QACjC,MAAM,YAAY,GAAG,eAAe,CAClC,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAC1E,CAAC;QACF,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,yBAAyB,CACjC,cAAc,KAAK,GAAG,CAAC,mCAAmC,CAC3D,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;IAC9C,CAAC;IACD,MAAM,IAAI,yBAAyB,CAAC,cAAc,KAAK,GAAG,CAAC,yBAAyB,CAAC,CAAC;AACxF,CAAC;AAED,SAAS,eAAe,CAAC,KAAyB;IAChD,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC;IAC9B,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACvC,CAAC"}
|
package/dist/parser.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ParseAttachmentInput, ParsedAttachment } from './types.js';
|
|
2
|
-
export interface AttachmentParser {
|
|
3
|
-
parse(input: ParseAttachmentInput): Promise<ParsedAttachment>;
|
|
4
|
-
}
|
|
5
|
-
export declare class BasicAttachmentParser implements AttachmentParser {
|
|
6
|
-
parse(input: ParseAttachmentInput): Promise<ParsedAttachment>;
|
|
7
|
-
}
|
|
8
|
-
export declare class LiteParseAttachmentParser implements AttachmentParser {
|
|
9
|
-
private readonly fallback;
|
|
10
|
-
parse(input: ParseAttachmentInput): Promise<ParsedAttachment>;
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=parser.d.ts.map
|
package/dist/parser.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC/D;AAED,qBAAa,qBAAsB,YAAW,gBAAgB;IACtD,KAAK,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAkBpE;AAED,qBAAa,yBAA0B,YAAW,gBAAgB;IAChE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+B;IAElD,KAAK,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC;CA2BpE"}
|