@tstdl/base 0.92.150 → 0.92.151

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,6 +1,6 @@
1
1
  import type { Resolvable, resolveArgumentType } from '../injector/interfaces.js';
2
2
  import type { AiServiceOptions } from './ai.service.js';
3
- import type { FileContentPart, FileInput } from './types.js';
3
+ import { type FileContentPart, type FileInput } from './types.js';
4
4
  /**
5
5
  * Options for {@link AiFileService}.
6
6
  */
@@ -48,6 +48,8 @@ export declare class AiFileService implements Resolvable<AiFileServiceArgument>
48
48
  private getFile;
49
49
  private getFiles;
50
50
  private uploadFile;
51
+ private uploadFileVertex;
52
+ private uploadFileGenAi;
51
53
  private getBucket;
52
54
  private waitForFileActive;
53
55
  private waitForFilesActive;
@@ -4,7 +4,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { openAsBlob } from 'node:fs';
7
+ import { createReadStream } from 'node:fs';
8
+ import { stat } from 'node:fs/promises';
8
9
  import { Readable } from 'node:stream';
9
10
  import { ReadableStream as NodeReadableStream } from 'node:stream/web';
10
11
  import { Storage } from '@google-cloud/storage';
@@ -18,7 +19,9 @@ import { Logger } from '../logger/logger.js';
18
19
  import { createArray } from '../utils/array/array.js';
19
20
  import { backoffGenerator } from '../utils/backoff.js';
20
21
  import { formatBytes } from '../utils/format.js';
22
+ import { readBinaryStream } from '../utils/stream/stream-reader.js';
21
23
  import { assertDefinedPass, isBlob, isDefined, isUndefined } from '../utils/type-guards.js';
24
+ import { isPathFileInput } from './types.js';
22
25
  /**
23
26
  * Manages file uploads and state for use with AI models.
24
27
  * Handles both Google Generative AI File API and Google Cloud Storage for Vertex AI.
@@ -103,24 +106,67 @@ let AiFileService = class AiFileService {
103
106
  return files;
104
107
  }
105
108
  async uploadFile(fileInput, id) {
106
- const inputIsBlob = isBlob(fileInput);
107
- const blob = inputIsBlob
108
- ? fileInput
109
- : await openAsBlob(fileInput.path, { type: fileInput.mimeType });
110
- this.#logger.verbose(`Uploading file "${id}" (${formatBytes(blob.size)})...`);
111
109
  if (isDefined(this.#storage)) {
112
- const bucket = await this.getBucket();
113
- const file = bucket.file(id);
114
- const blobStream = Readable.fromWeb(blob.stream());
115
- await file.save(blobStream, { contentType: blob.type, resumable: false });
116
- return {
117
- id,
118
- name: id, // For Vertex, name is the GCS object id
119
- uri: `gs://${bucket.name}/${file.name}`,
120
- mimeType: blob.type,
121
- };
110
+ return await this.uploadFileVertex(fileInput, id);
122
111
  }
123
- const response = await this.#genAI.files.upload({ file: blob, config: { mimeType: blob.type } });
112
+ return await this.uploadFileGenAi(fileInput, id);
113
+ }
114
+ async uploadFileVertex(fileInput, id) {
115
+ const bucket = await this.getBucket();
116
+ const file = bucket.file(id);
117
+ let stream;
118
+ let contentType;
119
+ let size;
120
+ if (isBlob(fileInput)) {
121
+ stream = Readable.fromWeb(fileInput.stream());
122
+ contentType = fileInput.type;
123
+ size = fileInput.size;
124
+ }
125
+ else if (isPathFileInput(fileInput)) {
126
+ const stats = await stat(fileInput.path);
127
+ stream = createReadStream(fileInput.path);
128
+ contentType = fileInput.mimeType;
129
+ size = stats.size;
130
+ }
131
+ else {
132
+ stream = Readable.fromWeb(fileInput.stream);
133
+ contentType = fileInput.mimeType;
134
+ size = fileInput.size;
135
+ }
136
+ this.#logger.verbose(`Uploading file "${id}"${isDefined(size) ? ` (${formatBytes(size)})` : ''}...`);
137
+ await file.save(stream, { contentType, resumable: false });
138
+ return {
139
+ id,
140
+ name: id,
141
+ uri: `gs://${bucket.name}/${file.name}`,
142
+ mimeType: contentType,
143
+ };
144
+ }
145
+ async uploadFileGenAi(fileInput, id) {
146
+ let uploadData;
147
+ let contentType;
148
+ let size;
149
+ if (isBlob(fileInput)) {
150
+ uploadData = fileInput;
151
+ contentType = fileInput.type;
152
+ size = fileInput.size;
153
+ }
154
+ else if (isPathFileInput(fileInput)) {
155
+ const fileState = await stat(fileInput.path);
156
+ uploadData = fileInput.path;
157
+ contentType = fileInput.mimeType;
158
+ size = fileState.size;
159
+ }
160
+ else {
161
+ const fileBytes = await readBinaryStream(fileInput.stream);
162
+ const blob = new Blob([fileBytes], { type: fileInput.mimeType });
163
+ uploadData = blob;
164
+ contentType = blob.type;
165
+ size = blob.size;
166
+ }
167
+ this.#logger.verbose(`Uploading file "${id}" (${formatBytes(size)}) via GenAI API...`);
168
+ // upload supports paths and blobs, but not streams (yet)
169
+ const response = await this.#genAI.files.upload({ file: uploadData, config: { mimeType: contentType } });
124
170
  return {
125
171
  id,
126
172
  name: assertDefinedPass(response.name, 'Missing file name'),
package/ai/types.d.ts CHANGED
@@ -8,6 +8,10 @@ import type { ResolvedValueOrProvider, ValueOrAsyncProvider } from '../utils/val
8
8
  export type FileInput = {
9
9
  path: string;
10
10
  mimeType: string;
11
+ } | {
12
+ stream: ReadableStream<Uint8Array>;
13
+ mimeType: string;
14
+ size?: number;
11
15
  } | Blob;
12
16
  /**
13
17
  * A record of named function declarations, where each key is the function name.
@@ -202,3 +206,12 @@ export declare function defineFunction<P extends Record, T extends SchemaFunctio
202
206
  * @returns `true` if the declaration has a `handler` property, `false` otherwise.
203
207
  */
204
208
  export declare function isSchemaFunctionDeclarationWithHandler(declaration: SchemaFunctionDeclaration): declaration is SchemaFunctionDeclarationWithHandler;
209
+ export declare function isPathFileInput(input: FileInput): input is {
210
+ path: string;
211
+ mimeType: string;
212
+ };
213
+ export declare function isStreamFileInput(input: FileInput): input is {
214
+ stream: ReadableStream<Uint8Array>;
215
+ mimeType: string;
216
+ size?: number;
217
+ };
package/ai/types.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { hasOwnProperty } from '../utils/object/object.js';
2
+ import { isBlob } from '../utils/type-guards.js';
2
3
  /**
3
4
  * A helper function to define a set of function declarations with strong type inference.
4
5
  * @param declarations A record of function declarations.
@@ -24,3 +25,9 @@ export function defineFunction(declaration) {
24
25
  export function isSchemaFunctionDeclarationWithHandler(declaration) {
25
26
  return hasOwnProperty(declaration, 'handler');
26
27
  }
28
+ export function isPathFileInput(input) {
29
+ return !isBlob(input) && hasOwnProperty(input, 'path');
30
+ }
31
+ export function isStreamFileInput(input) {
32
+ return !isBlob(input) && hasOwnProperty(input, 'stream');
33
+ }
@@ -86,8 +86,8 @@ export declare const documentManagementApiDefinition: {
86
86
  resource: string;
87
87
  method: "POST";
88
88
  parameters: import("../../schema/index.js").ObjectSchema<{
89
- label: string;
90
89
  parentId: import("../../orm/schemas/uuid.js").Uuid | null;
90
+ label: string;
91
91
  metadata?: Partial<{
92
92
  attributes: import("../../orm/types.js").HasDefault<import("../../orm/schemas/json.js").Json<import("../../orm/entity.js").EntityMetadataAttributes>>;
93
93
  }> | undefined;
@@ -125,10 +125,10 @@ export declare const documentManagementApiDefinition: {
125
125
  method: "POST";
126
126
  parameters: import("../../schema/index.js").ObjectSchema<{
127
127
  date?: import("../../orm/types.js").NumericDate | null | undefined;
128
- summary?: string | null | undefined;
129
- title?: string | null | undefined;
130
128
  typeId?: import("../../orm/types.js").Uuid | null | undefined;
129
+ title?: string | null | undefined;
131
130
  subtitle?: string | null | undefined;
131
+ summary?: string | null | undefined;
132
132
  comment?: string | null | undefined;
133
133
  approval?: import("../models/document.model.js").DocumentApproval | undefined;
134
134
  originalFileName?: string | null | undefined;
@@ -177,8 +177,8 @@ export declare const documentManagementApiDefinition: {
177
177
  parameters: import("../../schema/index.js").ObjectSchema<{
178
178
  id: import("../../orm/types.js").IsPrimaryKey<import("../../orm/types.js").HasDefault<import("../../orm/schemas/uuid.js").Uuid>>;
179
179
  description?: string | null | undefined;
180
- label?: string | undefined;
181
180
  tenantId?: string | null | undefined;
181
+ label?: string | undefined;
182
182
  metadata?: Partial<{
183
183
  attributes: import("../../orm/types.js").HasDefault<import("../../orm/schemas/json.js").Json<import("../../orm/entity.js").EntityMetadataAttributes>>;
184
184
  }> | undefined;
@@ -324,8 +324,8 @@ export declare const documentManagementApiDefinition: {
324
324
  parameters: import("../../schema/index.js").ObjectSchema<{
325
325
  id: import("../../orm/types.js").IsPrimaryKey<import("../../orm/types.js").HasDefault<import("../../orm/schemas/uuid.js").Uuid>>;
326
326
  date?: import("../../orm/types.js").NumericDate | null | undefined;
327
- title?: string | null | undefined;
328
327
  typeId?: import("../../orm/types.js").Uuid | null | undefined;
328
+ title?: string | null | undefined;
329
329
  subtitle?: string | null | undefined;
330
330
  comment?: string | null | undefined;
331
331
  properties?: {
@@ -483,8 +483,8 @@ declare const _DocumentManagementApi: import("../../api/client/index.js").ApiCli
483
483
  resource: string;
484
484
  method: "POST";
485
485
  parameters: import("../../schema/index.js").ObjectSchema<{
486
- label: string;
487
486
  parentId: import("../../orm/schemas/uuid.js").Uuid | null;
487
+ label: string;
488
488
  metadata?: Partial<{
489
489
  attributes: import("../../orm/types.js").HasDefault<import("../../orm/schemas/json.js").Json<import("../../orm/entity.js").EntityMetadataAttributes>>;
490
490
  }> | undefined;
@@ -522,10 +522,10 @@ declare const _DocumentManagementApi: import("../../api/client/index.js").ApiCli
522
522
  method: "POST";
523
523
  parameters: import("../../schema/index.js").ObjectSchema<{
524
524
  date?: import("../../orm/types.js").NumericDate | null | undefined;
525
- summary?: string | null | undefined;
526
- title?: string | null | undefined;
527
525
  typeId?: import("../../orm/types.js").Uuid | null | undefined;
526
+ title?: string | null | undefined;
528
527
  subtitle?: string | null | undefined;
528
+ summary?: string | null | undefined;
529
529
  comment?: string | null | undefined;
530
530
  approval?: import("../models/document.model.js").DocumentApproval | undefined;
531
531
  originalFileName?: string | null | undefined;
@@ -574,8 +574,8 @@ declare const _DocumentManagementApi: import("../../api/client/index.js").ApiCli
574
574
  parameters: import("../../schema/index.js").ObjectSchema<{
575
575
  id: import("../../orm/types.js").IsPrimaryKey<import("../../orm/types.js").HasDefault<import("../../orm/schemas/uuid.js").Uuid>>;
576
576
  description?: string | null | undefined;
577
- label?: string | undefined;
578
577
  tenantId?: string | null | undefined;
578
+ label?: string | undefined;
579
579
  metadata?: Partial<{
580
580
  attributes: import("../../orm/types.js").HasDefault<import("../../orm/schemas/json.js").Json<import("../../orm/entity.js").EntityMetadataAttributes>>;
581
581
  }> | undefined;
@@ -721,8 +721,8 @@ declare const _DocumentManagementApi: import("../../api/client/index.js").ApiCli
721
721
  parameters: import("../../schema/index.js").ObjectSchema<{
722
722
  id: import("../../orm/types.js").IsPrimaryKey<import("../../orm/types.js").HasDefault<import("../../orm/schemas/uuid.js").Uuid>>;
723
723
  date?: import("../../orm/types.js").NumericDate | null | undefined;
724
- title?: string | null | undefined;
725
724
  typeId?: import("../../orm/types.js").Uuid | null | undefined;
725
+ title?: string | null | undefined;
726
726
  subtitle?: string | null | undefined;
727
727
  comment?: string | null | undefined;
728
728
  properties?: {
@@ -20,10 +20,10 @@ export declare const updateDocumentCollectionsParametersSchema: import("../../sc
20
20
  }>;
21
21
  export declare const createDocumentParametersSchema: import("../../schema/index.js").ObjectSchema<{
22
22
  date?: import("../../orm/types.js").NumericDate | null | undefined;
23
- summary?: string | null | undefined;
24
- title?: string | null | undefined;
25
23
  typeId?: import("../../orm/types.js").Uuid | null | undefined;
24
+ title?: string | null | undefined;
26
25
  subtitle?: string | null | undefined;
26
+ summary?: string | null | undefined;
27
27
  comment?: string | null | undefined;
28
28
  approval?: import("../models/document.model.js").DocumentApproval | undefined;
29
29
  originalFileName?: string | null | undefined;
@@ -53,8 +53,8 @@ export declare const createDocumentParametersSchema: import("../../schema/index.
53
53
  export declare const updateDocumentParametersSchema: import("../../schema/index.js").ObjectSchema<{
54
54
  id: import("../../orm/types.js").IsPrimaryKey<import("../../orm/types.js").HasDefault<import("../../orm/schemas/uuid.js").Uuid>>;
55
55
  date?: import("../../orm/types.js").NumericDate | null | undefined;
56
- title?: string | null | undefined;
57
56
  typeId?: import("../../orm/types.js").Uuid | null | undefined;
57
+ title?: string | null | undefined;
58
58
  subtitle?: string | null | undefined;
59
59
  comment?: string | null | undefined;
60
60
  properties?: {
@@ -97,8 +97,8 @@ export declare const createDocumentRequestsTemplateParametersSchema: import("../
97
97
  export declare const updateDocumentRequestsTemplateParametersSchema: import("../../schema/index.js").ObjectSchema<{
98
98
  id: import("../../orm/types.js").IsPrimaryKey<import("../../orm/types.js").HasDefault<import("../../orm/schemas/uuid.js").Uuid>>;
99
99
  description?: string | null | undefined;
100
- label?: string | undefined;
101
100
  tenantId?: string | null | undefined;
101
+ label?: string | undefined;
102
102
  metadata?: Partial<{
103
103
  attributes: import("../../orm/types.js").HasDefault<import("../../orm/schemas/json.js").Json<import("../../orm/entity.js").EntityMetadataAttributes>>;
104
104
  }> | undefined;
@@ -181,8 +181,8 @@ export declare const setDocumentPropertiesParametersSchema: import("../../schema
181
181
  documentId: string;
182
182
  }>;
183
183
  export declare const createDocumentCategoryParametersSchema: import("../../schema/index.js").ObjectSchema<{
184
- label: string;
185
184
  parentId: import("../../orm/schemas/uuid.js").Uuid | null;
185
+ label: string;
186
186
  metadata?: Partial<{
187
187
  attributes: import("../../orm/types.js").HasDefault<import("../../orm/schemas/json.js").Json<import("../../orm/entity.js").EntityMetadataAttributes>>;
188
188
  }> | undefined;
@@ -212,8 +212,8 @@ export declare const rejectDocumentRequestParametersSchema: import("../../schema
212
212
  }> | undefined;
213
213
  }>;
214
214
  export declare const createDocumentPropertyParametersSchema: import("../../schema/index.js").ObjectSchema<{
215
- label: string;
216
215
  dataType: import("../../orm/types.js").Enum<import("../models/document-property.model.js").DocumentPropertyDataType>;
216
+ label: string;
217
217
  metadata?: Partial<{
218
218
  attributes: import("../../orm/types.js").HasDefault<import("../../orm/schemas/json.js").Json<import("../../orm/entity.js").EntityMetadataAttributes>>;
219
219
  }> | undefined;
@@ -1,7 +1,6 @@
1
1
  import { resolveArgumentType } from '../../injector/index.js';
2
2
  import type { Resolvable } from '../../injector/interfaces.js';
3
- import type { ImageOptions } from '../image-service.js';
4
- import { ImageService } from '../image-service.js';
3
+ import { ImageService, type ImageOptions } from '../image-service.js';
5
4
  export type ImgproxyImageServiceConfig = {
6
5
  endpoint: string;
7
6
  key: string;
@@ -17,7 +17,7 @@ import { concatArrayBufferViews } from '../../utils/binary.js';
17
17
  import { importHmacKey, sign } from '../../utils/cryptography.js';
18
18
  import { decodeHex, encodeUtf8 } from '../../utils/encoding.js';
19
19
  import { isDefined } from '../../utils/type-guards.js';
20
- import { ImageService } from '../image-service.js';
20
+ import { ImageOrigin, ImageService } from '../image-service.js';
21
21
  export const IMGPROXY_IMAGE_SERVICE_CONFIG = injectionToken('ImgproxyImageServiceConfig');
22
22
  let ImgproxyImageService = class ImgproxyImageService extends ImageService {
23
23
  #keyBytes;
@@ -75,16 +75,16 @@ async function signString(keyBytes, saltBytes, target, size = 32) {
75
75
  }
76
76
  function convertOrigin(origin) {
77
77
  switch (origin) {
78
- case 'center': return 'ce';
79
- case 'smart': return 'sm';
80
- case 'top': return 'no';
81
- case 'left': return 'we';
82
- case 'right': return 'ea';
83
- case 'bottom': return 'so';
84
- case 'topleft': return 'nowe';
85
- case 'topright': return 'noea';
86
- case 'bottomleft': return 'sowe';
87
- case 'bottomright': return 'soea';
78
+ case ImageOrigin.Center: return 'ce';
79
+ case ImageOrigin.Smart: return 'sm';
80
+ case ImageOrigin.Top: return 'no';
81
+ case ImageOrigin.Left: return 'we';
82
+ case ImageOrigin.Right: return 'ea';
83
+ case ImageOrigin.Bottom: return 'so';
84
+ case ImageOrigin.TopLeft: return 'nowe';
85
+ case ImageOrigin.TopRight: return 'noea';
86
+ case ImageOrigin.BottomLeft: return 'sowe';
87
+ case ImageOrigin.BottomRight: return 'soea';
88
88
  default: throw new Error();
89
89
  }
90
90
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.92.150",
3
+ "version": "0.92.151",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
package/utils/binary.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { BinaryData, Type } from '../types/index.js';
1
+ import type { BinaryData } from '../types/index.js';
2
2
  /**
3
3
  * Get ArrayBuffer from binary data
4
4
  * @param data data to get ArrayBuffer from
@@ -11,6 +11,5 @@ export declare function toArrayBuffer(data: BinaryData, clone?: boolean): ArrayB
11
11
  * @param clone whether to clone buffer or not
12
12
  */
13
13
  export declare function toUint8Array(data: BinaryData, clone?: boolean): Uint8Array;
14
- export declare function concatArrayBuffers(buffers: ArrayBufferLike[]): ArrayBufferLike;
15
- export declare function concatArrayBufferViews<T extends ArrayBufferView>(arrays: T[], totalLength?: number): T;
16
- export declare function concatArrayBufferViews<T extends ArrayBufferView>(arrays: ArrayBufferView[], targetType: Type<T, [ArrayBufferLike, number, number]>, totalLength?: number): T;
14
+ export declare function concatArrayBuffers(buffers: readonly ArrayBufferLike[]): ArrayBuffer;
15
+ export declare function concatArrayBufferViews(arrays: readonly ArrayBufferView[], totalLength?: number): Uint8Array<ArrayBuffer>;
package/utils/binary.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { supportsBuffer } from '../supports.js';
2
- import { typeExtends } from './index.js';
3
- import { assert, isArrayBuffer, isFunction, isNumber } from './type-guards.js';
2
+ import { assert, isArrayBuffer, isUint8Array } from './type-guards.js';
4
3
  /**
5
4
  * Get ArrayBuffer from binary data
6
5
  * @param data data to get ArrayBuffer from
@@ -36,13 +35,10 @@ export function concatArrayBuffers(buffers) {
36
35
  const bytes = concatArrayBufferViews(arrays);
37
36
  return bytes.buffer;
38
37
  }
39
- export function concatArrayBufferViews(arrays, totalLengthOrTargetType, totalLengthOrNothing) {
38
+ export function concatArrayBufferViews(arrays, totalLength) {
40
39
  assert(arrays.length > 0, 'No array provided.');
41
- const totalLength = isNumber(totalLengthOrTargetType) ? totalLengthOrTargetType : totalLengthOrNothing;
42
- const type = isFunction(totalLengthOrTargetType) ? totalLengthOrTargetType : arrays[0].constructor;
43
- if (supportsBuffer && typeExtends(type, Uint8Array)) {
44
- const merged = Buffer.concat(arrays, totalLength);
45
- return new type(merged.buffer, merged.byteOffset, merged.byteLength);
40
+ if (supportsBuffer && arrays.every((array) => isUint8Array(array))) {
41
+ return Buffer.concat(arrays, totalLength);
46
42
  }
47
43
  const totalBytes = totalLength ?? arrays.reduce((sum, array) => sum + array.byteLength, 0);
48
44
  const merged = new Uint8Array(totalBytes);
@@ -52,5 +48,5 @@ export function concatArrayBufferViews(arrays, totalLengthOrTargetType, totalLen
52
48
  merged.set(uint8Array, currentIndex);
53
49
  currentIndex += uint8Array.byteLength;
54
50
  }
55
- return new type(merged.buffer, merged.byteOffset, merged.byteLength);
51
+ return merged;
56
52
  }
@@ -6,5 +6,5 @@ export type ReadBinaryStreamOptions = {
6
6
  /** Action if source stream has less bytes than provided length */
7
7
  onLengthSubceed?: 'error' | 'close' | 'leave-open';
8
8
  };
9
- export declare function readBinaryStream(iterableOrStream: AnyIterable<ArrayBufferView> | ReadableStream<ArrayBufferView>, { length, onLengthExceed, onLengthSubceed }?: ReadBinaryStreamOptions): Promise<Uint8Array>;
9
+ export declare function readBinaryStream(iterableOrStream: AnyIterable<ArrayBufferView> | ReadableStream<ArrayBufferView>, { length, onLengthExceed, onLengthSubceed }?: ReadBinaryStreamOptions): Promise<Uint8Array<ArrayBuffer>>;
10
10
  export declare function readTextStream(iterableOrStream: AsyncIterable<string> | ReadableStream<string>): Promise<string>;
@@ -114,7 +114,7 @@ export async function readBinaryStream(iterableOrStream, { length, onLengthExcee
114
114
  if (views.length == 0) {
115
115
  return new Uint8Array(0);
116
116
  }
117
- return concatArrayBufferViews(views, Uint8Array, totalLength);
117
+ return concatArrayBufferViews(views, totalLength);
118
118
  }
119
119
  export async function readTextStream(iterableOrStream) {
120
120
  const iterable = isAsyncIterable(iterableOrStream) ? iterableOrStream : getReadableStreamIterable(iterableOrStream);