@abyss-project/tools 2.11.0 → 2.13.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.
@@ -1,13 +1,6 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
- /// <reference types="node" />
4
1
  import type { IScanOptions, IListScansQuery, IScanResponse, IScanSyncResponse, IScanAsyncResponse, IGetScanResponse, IPaginateScanResponse } from '../types';
5
- export type ProbeScanFileInput = Buffer | Uint8Array | NodeJS.ReadableStream | Blob;
6
- export interface BuiltScanForm {
7
- form: unknown;
8
- headers: Record<string, string>;
9
- }
10
- export declare function buildScanForm(file: ProbeScanFileInput, options: IScanOptions): Promise<BuiltScanForm>;
2
+ export type ProbeScanFileInput = Blob | Uint8Array;
3
+ export declare function buildScanForm(file: ProbeScanFileInput, options: IScanOptions): FormData;
11
4
  export declare const scan: (file: ProbeScanFileInput, options?: IScanOptions, apiKey?: string) => Promise<IScanResponse>;
12
5
  export declare const scanSync: (file: ProbeScanFileInput, options?: Omit<IScanOptions, 'mode' | 'callbackUrl'>, apiKey?: string) => Promise<IScanSyncResponse>;
13
6
  export declare const scanAsync: (file: ProbeScanFileInput, options?: Omit<IScanOptions, 'mode'>, apiKey?: string) => Promise<IScanAsyncResponse>;
@@ -17,42 +17,32 @@ function serializeProbeQuery(query) {
17
17
  }
18
18
  return out;
19
19
  }
20
- function isBrowserEnv() {
21
- return typeof window !== 'undefined' && typeof FormData !== 'undefined';
20
+ function toScanFilePart(file, mimeType) {
21
+ if (file instanceof Blob)
22
+ return file;
23
+ if (file instanceof Uint8Array)
24
+ return new Blob([file], { type: mimeType ?? '' });
25
+ const isStream = typeof file?.pipe === 'function';
26
+ throw new TypeError(`A probe scan file must be a Blob (a browser File, or fs.openAsBlob(path) on Node), ` +
27
+ `a Buffer or a Uint8Array — received ${isStream ? 'a stream' : typeof file}. ` +
28
+ `On Node, pass \`await fs.openAsBlob(path)\`: a file-backed Blob is streamed from ` +
29
+ `disk, so the file is never buffered in memory.`);
22
30
  }
23
- async function loadNodeFormData() {
24
- const nodeRequire = new Function('return require')();
25
- return nodeRequire('form-data');
26
- }
27
- async function buildScanForm(file, options) {
28
- const filename = options.filename ?? 'file';
29
- if (isBrowserEnv()) {
30
- const form = new FormData();
31
- const blob = file instanceof Blob ? file : new Blob([file], { type: options.mimeType });
32
- form.append('file', blob, filename);
33
- if (options.context)
34
- form.append('context', JSON.stringify(options.context));
35
- if (options.callbackUrl)
36
- form.append('callbackUrl', options.callbackUrl);
37
- return { form, headers: {} };
38
- }
39
- const FormDataCtor = await loadNodeFormData();
40
- const form = new FormDataCtor();
41
- const filePart = Buffer.isBuffer(file) || file instanceof Uint8Array ? Buffer.from(file) : file;
42
- form.append('file', filePart, { filename, contentType: options.mimeType });
31
+ function buildScanForm(file, options) {
32
+ const form = new FormData();
33
+ form.append('file', toScanFilePart(file, options.mimeType), options.filename ?? 'file');
43
34
  if (options.context)
44
35
  form.append('context', JSON.stringify(options.context));
45
36
  if (options.callbackUrl)
46
37
  form.append('callbackUrl', options.callbackUrl);
47
- const headers = typeof form.getHeaders === 'function' ? form.getHeaders() : {};
48
- return { form, headers };
38
+ return form;
49
39
  }
50
40
  exports.buildScanForm = buildScanForm;
51
41
  const scan = async (file, options = {}, apiKey) => {
52
- const { form, headers } = await buildScanForm(file, options);
42
+ const form = buildScanForm(file, options);
53
43
  return (await __1.AbyssToolsCore.axios.post('scan', form, {
54
44
  params: serializeProbeQuery({ mode: options.mode, organizationId: options.organizationId }),
55
- headers: { ...headers, ...authHeader(apiKey) },
45
+ headers: authHeader(apiKey),
56
46
  maxBodyLength: Infinity,
57
47
  maxContentLength: Infinity,
58
48
  })).data;
@@ -1 +1 @@
1
- {"version":3,"file":"probe-scan.api.js","sourceRoot":"","sources":["../../src/api/probe-scan.api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"probe-scan.api.js","sourceRoot":"","sources":["../../src/api/probe-scan.api.ts"],"names":[],"mappings":"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"}
@@ -34,4 +34,14 @@ void _scanSync;
34
34
  void _scanAsync;
35
35
  void _getScan;
36
36
  void _listScans;
37
+ const _fromBlob = blob;
38
+ const _fromBytes = bytes;
39
+ const _fromBuffer = buffer;
40
+ const _fromStream = stream;
41
+ void _fromBlob;
42
+ void _fromBytes;
43
+ void _fromBuffer;
44
+ void _fromStream;
45
+ const _form = api.buildScanForm(blob, { filename: 'f.bin' });
46
+ void _form;
37
47
  //# sourceMappingURL=probe-scan.api.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"probe-scan.api.test.js","sourceRoot":"","sources":["../../src/api/probe-scan.api.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAKA,sDAAwC;AAGxC,MAAM,KAAK,GAAoB,GAAG,CAAC,IAAI,CAAC;AACxC,MAAM,SAAS,GAAwB,GAAG,CAAC,QAAQ,CAAC;AACpD,MAAM,UAAU,GAAyB,GAAG,CAAC,SAAS,CAAC;AACvD,MAAM,QAAQ,GAAuB,GAAG,CAAC,OAAO,CAAC;AACjD,MAAM,UAAU,GAAyB,GAAG,CAAC,SAAS,CAAC;AAEvD,KAAK,KAAK,CAAC;AACX,KAAK,SAAS,CAAC;AACf,KAAK,UAAU,CAAC;AAChB,KAAK,QAAQ,CAAC;AACd,KAAK,UAAU,CAAC"}
1
+ {"version":3,"file":"probe-scan.api.test.js","sourceRoot":"","sources":["../../src/api/probe-scan.api.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAKA,sDAAwC;AAGxC,MAAM,KAAK,GAAoB,GAAG,CAAC,IAAI,CAAC;AACxC,MAAM,SAAS,GAAwB,GAAG,CAAC,QAAQ,CAAC;AACpD,MAAM,UAAU,GAAyB,GAAG,CAAC,SAAS,CAAC;AACvD,MAAM,QAAQ,GAAuB,GAAG,CAAC,OAAO,CAAC;AACjD,MAAM,UAAU,GAAyB,GAAG,CAAC,SAAS,CAAC;AAEvD,KAAK,KAAK,CAAC;AACX,KAAK,SAAS,CAAC;AACf,KAAK,UAAU,CAAC;AAChB,KAAK,QAAQ,CAAC;AACd,KAAK,UAAU,CAAC;AAYhB,MAAM,SAAS,GAA2B,IAAI,CAAC;AAC/C,MAAM,UAAU,GAA2B,KAAK,CAAC;AACjD,MAAM,WAAW,GAA2B,MAAM,CAAC;AAEnD,MAAM,WAAW,GAA2B,MAAM,CAAC;AAEnD,KAAK,SAAS,CAAC;AACf,KAAK,UAAU,CAAC;AAChB,KAAK,WAAW,CAAC;AACjB,KAAK,WAAW,CAAC;AAIjB,MAAM,KAAK,GAAa,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;AACvE,KAAK,KAAK,CAAC"}
@@ -17,10 +17,10 @@ function serializeProbeQuery(query) {
17
17
  return out;
18
18
  }
19
19
  const scanApplication = async (applicationId, file, options = {}, applicationApiKey) => {
20
- const { form, headers } = await (0, probe_scan_api_1.buildScanForm)(file, options);
20
+ const form = (0, probe_scan_api_1.buildScanForm)(file, options);
21
21
  return (await __1.AbyssToolsCore.axios.post(`application/${applicationId}/scan`, form, {
22
22
  params: serializeProbeQuery({ mode: options.mode }),
23
- headers: { ...headers, ...authHeaderApplication(applicationApiKey) },
23
+ headers: authHeaderApplication(applicationApiKey),
24
24
  maxBodyLength: Infinity,
25
25
  maxContentLength: Infinity,
26
26
  })).data;
@@ -1 +1 @@
1
- {"version":3,"file":"probe-scan.application.api.js","sourceRoot":"","sources":["../../src/api/probe-scan.application.api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"probe-scan.application.api.js","sourceRoot":"","sources":["../../src/api/probe-scan.application.api.ts"],"names":[],"mappings":";;;AA4BA,0BAAgE;AAChE,oCAAyC;AAUzC,qDAAiD;AAGjD,SAAS,qBAAqB,CAAC,iBAA0B;IACvD,OAAO,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,8BAA0B,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACtF,CAAC;AASD,SAAS,mBAAmB,CAAmB,KAAQ;IACrD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QAC5E,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QACpD,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACjE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAeM,MAAM,eAAe,GAAG,KAAK,EAClC,aAAqB,EACrB,IAAwB,EACxB,UAAgD,EAAE,EAClD,iBAA0B,EACF,EAAE;IAC1B,MAAM,IAAI,GAAG,IAAA,8BAAa,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,CACL,MAAM,kBAAc,CAAC,KAAK,CAAC,IAAI,CAAgB,eAAe,aAAa,OAAO,EAAE,IAAI,EAAE;QACxF,MAAM,EAAE,mBAAmB,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;QACnD,OAAO,EAAE,qBAAqB,CAAC,iBAAiB,CAAC;QACjD,aAAa,EAAE,QAAQ;QACvB,gBAAgB,EAAE,QAAQ;KAC3B,CAAC,CACH,CAAC,IAAI,CAAC;AACT,CAAC,CAAC;AAfW,QAAA,eAAe,mBAe1B;AAGK,MAAM,mBAAmB,GAAG,KAAK,EACtC,aAAqB,EACrB,IAAwB,EACxB,UAAyE,EAAE,EAC3E,iBAA0B,EACE,EAAE,CAC9B,IAAA,uBAAe,EACb,aAAa,EACb,IAAI,EACJ,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,qBAAa,CAAC,IAAI,EAAE,EACxC,iBAAiB,CACY,CAAC;AAXrB,QAAA,mBAAmB,uBAWE;AAG3B,MAAM,oBAAoB,GAAG,KAAK,EACvC,aAAqB,EACrB,IAAwB,EACxB,UAAyD,EAAE,EAC3D,iBAA0B,EACG,EAAE,CAC/B,IAAA,uBAAe,EACb,aAAa,EACb,IAAI,EACJ,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,qBAAa,CAAC,KAAK,EAAE,EACzC,iBAAiB,CACa,CAAC;AAXtB,QAAA,oBAAoB,wBAWE;AAU5B,MAAM,kBAAkB,GAAG,KAAK,EACrC,aAAqB,EACrB,MAAc,EACd,iBAA0B,EACC,EAAE,CAC7B,CACE,MAAM,kBAAc,CAAC,KAAK,CAAC,GAAG,CAC5B,eAAe,aAAa,SAAS,MAAM,EAAE,EAC7C,EAAE,OAAO,EAAE,qBAAqB,CAAC,iBAAiB,CAAC,EAAE,CACtD,CACF,CAAC,IAAI,CAAC;AAVI,QAAA,kBAAkB,sBAUtB;AAQF,MAAM,oBAAoB,GAAG,KAAK,EACvC,aAAqB,EACrB,QAAiD,EAAE,EACnD,iBAA0B,EACM,EAAE,CAClC,CACE,MAAM,kBAAc,CAAC,KAAK,CAAC,GAAG,CAAwB,eAAe,aAAa,OAAO,EAAE;IACzF,MAAM,EAAE,mBAAmB,CAAC,KAAK,CAAC;IAClC,OAAO,EAAE,qBAAqB,CAAC,iBAAiB,CAAC;CAClD,CAAC,CACH,CAAC,IAAI,CAAC;AAVI,QAAA,oBAAoB,wBAUxB"}
@@ -34,4 +34,8 @@ void _scanSync;
34
34
  void _scanAsync;
35
35
  void _getScan;
36
36
  void _listScans;
37
+ const _fromBlob = blob;
38
+ const _fromStream = stream;
39
+ void _fromBlob;
40
+ void _fromStream;
37
41
  //# sourceMappingURL=probe-scan.application.api.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"probe-scan.application.api.test.js","sourceRoot":"","sources":["../../src/api/probe-scan.application.api.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAKA,kEAAoD;AAGpD,MAAM,KAAK,GAA+B,GAAG,CAAC,eAAe,CAAC;AAC9D,MAAM,SAAS,GAAmC,GAAG,CAAC,mBAAmB,CAAC;AAC1E,MAAM,UAAU,GAAoC,GAAG,CAAC,oBAAoB,CAAC;AAC7E,MAAM,QAAQ,GAAkC,GAAG,CAAC,kBAAkB,CAAC;AACvE,MAAM,UAAU,GAAoC,GAAG,CAAC,oBAAoB,CAAC;AAE7E,KAAK,KAAK,CAAC;AACX,KAAK,SAAS,CAAC;AACf,KAAK,UAAU,CAAC;AAChB,KAAK,QAAQ,CAAC;AACd,KAAK,UAAU,CAAC"}
1
+ {"version":3,"file":"probe-scan.application.api.test.js","sourceRoot":"","sources":["../../src/api/probe-scan.application.api.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAKA,kEAAoD;AAGpD,MAAM,KAAK,GAA+B,GAAG,CAAC,eAAe,CAAC;AAC9D,MAAM,SAAS,GAAmC,GAAG,CAAC,mBAAmB,CAAC;AAC1E,MAAM,UAAU,GAAoC,GAAG,CAAC,oBAAoB,CAAC;AAC7E,MAAM,QAAQ,GAAkC,GAAG,CAAC,kBAAkB,CAAC;AACvE,MAAM,UAAU,GAAoC,GAAG,CAAC,oBAAoB,CAAC;AAE7E,KAAK,KAAK,CAAC;AACX,KAAK,SAAS,CAAC;AACf,KAAK,UAAU,CAAC;AAChB,KAAK,QAAQ,CAAC;AACd,KAAK,UAAU,CAAC;AAShB,MAAM,SAAS,GAAkD,IAAI,CAAC;AAEtE,MAAM,WAAW,GAAkD,MAAM,CAAC;AAE1E,KAAK,SAAS,CAAC;AACf,KAAK,WAAW,CAAC"}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@abyss-project/tools",
3
- "version": "2.11.0",
3
+ "version": "2.13.0",
4
4
  "description": "Core package to interact with Abyss-Project Tools",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "engines": {
8
- "node": ">=18"
8
+ "node": ">=19.8"
9
9
  },
10
10
  "repository": {
11
11
  "type": "git",
@@ -18,4 +18,30 @@ void _scanAsync;
18
18
  void _getScan;
19
19
  void _listScans;
20
20
 
21
+ // The accepted file inputs (#519). A Blob covers the browser's File and Node's
22
+ // file-backed fs.openAsBlob(path); raw bytes are accepted as a Uint8Array (and
23
+ // therefore a Buffer). A Node stream is refused AT COMPILE TIME: the body is a
24
+ // spec FormData, whose parts need a known length, so honouring a stream would
25
+ // mean buffering up to 2 GiB in memory.
26
+ declare const blob: Blob;
27
+ declare const bytes: Uint8Array;
28
+ declare const buffer: Buffer;
29
+ declare const stream: NodeJS.ReadableStream;
30
+
31
+ const _fromBlob: api.ProbeScanFileInput = blob;
32
+ const _fromBytes: api.ProbeScanFileInput = bytes;
33
+ const _fromBuffer: api.ProbeScanFileInput = buffer;
34
+ // @ts-expect-error a Readable stream is not an accepted scan input since 2.12.0
35
+ const _fromStream: api.ProbeScanFileInput = stream;
36
+
37
+ void _fromBlob;
38
+ void _fromBytes;
39
+ void _fromBuffer;
40
+ void _fromStream;
41
+
42
+ // buildScanForm returns the FormData alone — axios sets the multipart
43
+ // content type and boundary, so there are no headers to merge in.
44
+ const _form: FormData = api.buildScanForm(blob, { filename: 'f.bin' });
45
+ void _form;
46
+
21
47
  export {};
@@ -6,13 +6,20 @@
6
6
  // add no extra path segment (`@Controller({ prefixPath: '/scan' })`), so
7
7
  // these calls hit `scan`/`scan/:id` directly — no `probe/` prefix.
8
8
  //
9
- // File-upload dual environment handling (browser `FormData`/`Blob` vs Node
10
- // `Buffer`/stream + the `form-data` package) mirrors this package's own
11
- // extraction.api.ts (`detect`/`postExtract`): AbyssProbe is meant to be
12
- // called from the abyss-main UI (a browser) as well as from Node services
13
- // (abyss-storage, external integrators). `form-data` is lazy-`require`d
14
- // (never statically imported) so a browser bundle never tries to resolve
15
- // the Node-only package.
9
+ // Multipart bodies are built with the global `FormData` + `Blob` — the same
10
+ // code in a browser and on Node, mirroring this package's own
11
+ // extraction.api.ts. axios serializes a spec-compliant FormData on both and
12
+ // sets the multipart boundary itself, so no content-type header is ever set by
13
+ // hand. AbyssProbe is called from the abyss-main UI (a browser) as well as
14
+ // from Node services (abyss-storage, external integrators).
15
+ //
16
+ // A Node caller holding a file ON DISK passes `await fs.openAsBlob(path)`,
17
+ // which requires Node >= 19.8 — hence `engines.node` in package.json.
18
+ // `FormData` and `Blob` alone would only need Node 18, but openAsBlob is this
19
+ // client's documented way to send a file, and promising 18.x only to fail at
20
+ // runtime is worse than refusing the install. A caller that already holds its
21
+ // bytes passes a `Buffer`/`Uint8Array` and has no such constraint (see
22
+ // {@link ProbeScanFileInput}).
16
23
  //
17
24
  // `authHeader`/`serializeProbeQuery` are kept LOCAL and unexported (not a
18
25
  // shared utils file) — same convention as every other extract/*.api.ts file
@@ -61,60 +68,65 @@ function serializeProbeQuery<T extends object>(query: T): Record<string, unknown
61
68
  return out;
62
69
  }
63
70
 
64
- /** Anything `sdk.probe.scan` accepts as the file to submit. */
65
- export type ProbeScanFileInput = Buffer | Uint8Array | NodeJS.ReadableStream | Blob;
66
-
67
- function isBrowserEnv(): boolean {
68
- return typeof window !== 'undefined' && typeof FormData !== 'undefined';
69
- }
70
-
71
- async function loadNodeFormData(): Promise<any> {
72
- // Indirect eval so bundlers (esbuild/vite/webpack) do not try to resolve
73
- // the Node-only "form-data" package when this file is included in a
74
- // browser bundle. The require only ever runs at runtime on Node.
75
- // eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func
76
- const nodeRequire: NodeRequire = new Function('return require')();
77
- return nodeRequire('form-data');
78
- }
71
+ /**
72
+ * Anything `sdk.probe.scan` accepts as the file to submit.
73
+ *
74
+ * `Blob` covers the browser's `File` (a `Blob` subclass) and, on Node, a
75
+ * FILE-BACKED blob from `await fs.openAsBlob(path)` (Node >= 19.8): its bytes
76
+ * are read from disk as the request body is written, so scanning a file at the
77
+ * 2 GiB ceiling never holds the file in memory. `Uint8Array` (and therefore
78
+ * `Buffer`) is for a caller that already holds the bytes.
79
+ *
80
+ * A Node `Readable` is NOT accepted. The body is a spec `FormData`, whose
81
+ * parts must have a known length, so a stream could only be honoured by
82
+ * buffering it whole — precisely what a 2 GiB scan must not do. A caller
83
+ * holding a path passes `await fs.openAsBlob(path)` instead.
84
+ */
85
+ export type ProbeScanFileInput = Blob | Uint8Array;
79
86
 
80
- export interface BuiltScanForm {
81
- form: unknown;
82
- headers: Record<string, string>;
87
+ /**
88
+ * The file as one multipart part.
89
+ *
90
+ * A `Blob` is used as-is, keeping whatever streaming its implementation gives
91
+ * (a file-backed `openAsBlob` reads from disk lazily); raw bytes are wrapped
92
+ * in a `Blob` carrying `mimeType`. `Buffer` is never named here — this code
93
+ * also runs in a browser bundle, where the global does not exist — and
94
+ * `Buffer` is a `Uint8Array` subclass, so the check below already covers it.
95
+ *
96
+ * Anything else is refused with an actionable message. Until 2.12.0 the same
97
+ * call died on Node with `ReferenceError: require is not defined`, thrown by a
98
+ * `form-data` loader before any request was made (#519): it named neither the
99
+ * cause nor the fix.
100
+ */
101
+ function toScanFilePart(file: ProbeScanFileInput, mimeType?: string): Blob {
102
+ if (file instanceof Blob) return file;
103
+ if (file instanceof Uint8Array) return new Blob([file], { type: mimeType ?? '' });
104
+
105
+ const isStream = typeof (file as { pipe?: unknown } | null | undefined)?.pipe === 'function';
106
+ throw new TypeError(
107
+ `A probe scan file must be a Blob (a browser File, or fs.openAsBlob(path) on Node), ` +
108
+ `a Buffer or a Uint8Array — received ${isStream ? 'a stream' : typeof file}. ` +
109
+ `On Node, pass \`await fs.openAsBlob(path)\`: a file-backed Blob is streamed from ` +
110
+ `disk, so the file is never buffered in memory.`,
111
+ );
83
112
  }
84
113
 
85
114
  /**
86
115
  * Exported (not just this file's own `scan` internals) so
87
116
  * probe-scan.application.api.ts reuses this EXACT multipart-building logic
88
- * (browser `FormData`/`Blob` vs Node `Buffer`/stream + lazy-required
89
- * `form-data`) rather than duplicating it — the file-upload contract is
90
- * identical for a personal/org caller and an application caller; only the
91
- * URL/auth differ (see that file's header comment).
117
+ * rather than duplicating it — the file-upload contract is identical for a
118
+ * personal/org caller and an application caller; only the URL/auth differ
119
+ * (see that file's header comment).
120
+ *
121
+ * Returns the form alone: axios sets the multipart content type, boundary
122
+ * included, so there is no header for the caller to merge in.
92
123
  */
93
- export async function buildScanForm(
94
- file: ProbeScanFileInput,
95
- options: IScanOptions,
96
- ): Promise<BuiltScanForm> {
97
- const filename = options.filename ?? 'file';
98
-
99
- if (isBrowserEnv()) {
100
- const form = new FormData();
101
- const blob =
102
- file instanceof Blob ? file : new Blob([file as BlobPart], { type: options.mimeType });
103
- form.append('file', blob, filename);
104
- if (options.context) form.append('context', JSON.stringify(options.context));
105
- if (options.callbackUrl) form.append('callbackUrl', options.callbackUrl);
106
- return { form, headers: {} };
107
- }
108
-
109
- const FormDataCtor = await loadNodeFormData();
110
- const form = new FormDataCtor();
111
- const filePart =
112
- Buffer.isBuffer(file) || file instanceof Uint8Array ? Buffer.from(file as Uint8Array) : file;
113
- form.append('file', filePart, { filename, contentType: options.mimeType });
124
+ export function buildScanForm(file: ProbeScanFileInput, options: IScanOptions): FormData {
125
+ const form = new FormData();
126
+ form.append('file', toScanFilePart(file, options.mimeType), options.filename ?? 'file');
114
127
  if (options.context) form.append('context', JSON.stringify(options.context));
115
128
  if (options.callbackUrl) form.append('callbackUrl', options.callbackUrl);
116
- const headers = typeof form.getHeaders === 'function' ? form.getHeaders() : {};
117
- return { form, headers };
129
+ return form;
118
130
  }
119
131
 
120
132
  /**
@@ -134,11 +146,11 @@ export const scan = async (
134
146
  options: IScanOptions = {},
135
147
  apiKey?: string,
136
148
  ): Promise<IScanResponse> => {
137
- const { form, headers } = await buildScanForm(file, options);
149
+ const form = buildScanForm(file, options);
138
150
  return (
139
151
  await AbyssToolsCore.axios.post<IScanResponse>('scan', form, {
140
152
  params: serializeProbeQuery({ mode: options.mode, organizationId: options.organizationId }),
141
- headers: { ...headers, ...authHeader(apiKey) },
153
+ headers: authHeader(apiKey),
142
154
  maxBodyLength: Infinity,
143
155
  maxContentLength: Infinity,
144
156
  })
@@ -18,4 +18,18 @@ void _scanAsync;
18
18
  void _getScan;
19
19
  void _listScans;
20
20
 
21
+ // The application client takes the SAME file input as the personal one (it
22
+ // reuses buildScanForm verbatim) — abyss-storage, its main caller, hands over
23
+ // `await fs.openAsBlob(path)`. A stream is refused at compile time (#519); see
24
+ // probe-scan.api.test.ts for the full input matrix.
25
+ declare const blob: Blob;
26
+ declare const stream: NodeJS.ReadableStream;
27
+
28
+ const _fromBlob: Parameters<typeof api.scanSyncApplication>[1] = blob;
29
+ // @ts-expect-error a Readable stream is not an accepted scan input since 2.12.0
30
+ const _fromStream: Parameters<typeof api.scanSyncApplication>[1] = stream;
31
+
32
+ void _fromBlob;
33
+ void _fromStream;
34
+
21
35
  export {};
@@ -8,9 +8,9 @@
8
8
  // (abyss-storage, external integrations) authenticating with a project API
9
9
  // key instead of a personal/org session.
10
10
  //
11
- // Reuses probe-scan.api.ts's `buildScanForm` (same dual-environment
12
- // multipart handling — browser `FormData`/`Blob` vs Node `Buffer`/stream +
13
- // lazy-required `form-data`) and every request/response TYPE verbatim
11
+ // Reuses probe-scan.api.ts's `buildScanForm` (the global `FormData` + `Blob`,
12
+ // one code path for the browser and for Node — see that file's header for what
13
+ // a Node caller passes) and every request/response TYPE verbatim
14
14
  // (`IScanOptions`, `IListScansQuery`, `IScanResponse`, `IScanSyncResponse`,
15
15
  // `IScanAsyncResponse`, `IGetScanResponse`, `IPaginateScanResponse`) — never
16
16
  // redefined here. `organizationId` is `Omit`'d from every option/query type
@@ -79,11 +79,11 @@ export const scanApplication = async (
79
79
  options: Omit<IScanOptions, 'organizationId'> = {},
80
80
  applicationApiKey?: string,
81
81
  ): Promise<IScanResponse> => {
82
- const { form, headers } = await buildScanForm(file, options);
82
+ const form = buildScanForm(file, options);
83
83
  return (
84
84
  await AbyssToolsCore.axios.post<IScanResponse>(`application/${applicationId}/scan`, form, {
85
85
  params: serializeProbeQuery({ mode: options.mode }),
86
- headers: { ...headers, ...authHeaderApplication(applicationApiKey) },
86
+ headers: authHeaderApplication(applicationApiKey),
87
87
  maxBodyLength: Infinity,
88
88
  maxContentLength: Infinity,
89
89
  })
@@ -21,7 +21,11 @@ export interface IScanOptions {
21
21
  callbackUrl?: string;
22
22
  /** Filename reported to the server (defaults to `'file'`). Cosmetic only. */
23
23
  filename?: string;
24
- /** Content-Type hint used when constructing a Blob from a raw buffer/Uint8Array in a browser context. */
24
+ /**
25
+ * Content-Type stamped on the file part when the caller passes raw bytes
26
+ * (`Buffer`/`Uint8Array`). Ignored when the file is already a `Blob` — a
27
+ * browser `File` and `fs.openAsBlob(path)` carry their own type.
28
+ */
25
29
  mimeType?: string;
26
30
  }
27
31