@tstdl/base 0.93.62 → 0.93.64

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.
Files changed (34) hide show
  1. package/ai/genkit/helpers.d.ts +10 -0
  2. package/ai/genkit/helpers.js +14 -0
  3. package/ai/genkit/index.d.ts +2 -0
  4. package/ai/genkit/index.js +2 -0
  5. package/ai/genkit/module.d.ts +35 -0
  6. package/ai/genkit/module.js +56 -0
  7. package/ai/index.d.ts +1 -0
  8. package/ai/index.js +1 -0
  9. package/ai/prompts/format.d.ts +15 -0
  10. package/ai/prompts/format.js +17 -0
  11. package/ai/prompts/index.d.ts +3 -0
  12. package/ai/prompts/index.js +3 -0
  13. package/ai/prompts/instructions-formatter.d.ts +25 -0
  14. package/ai/prompts/instructions-formatter.js +166 -0
  15. package/ai/prompts/instructions.d.ts +3 -0
  16. package/ai/prompts/instructions.js +8 -0
  17. package/document-management/server/services/document-file.service.d.ts +2 -0
  18. package/document-management/server/services/document-file.service.js +10 -9
  19. package/document-management/server/services/document-management-ai.service.d.ts +1 -0
  20. package/document-management/server/services/document-management-ai.service.js +266 -133
  21. package/document-management/server/services/document.service.js +1 -2
  22. package/examples/document-management/main.js +6 -0
  23. package/json-path/json-path.js +1 -1
  24. package/orm/server/repository.js +4 -6
  25. package/package.json +10 -6
  26. package/pdf/utils.js +1 -1
  27. package/schema/converters/zod-converter.d.ts +1 -1
  28. package/schema/converters/zod-converter.js +2 -13
  29. package/schema/converters/zod-v3-converter.d.ts +3 -3
  30. package/utils/file-reader.d.ts +0 -1
  31. package/utils/file-reader.js +4 -7
  32. package/utils/object/object.d.ts +4 -2
  33. package/utils/object/object.js +30 -21
  34. package/utils/stream/from-promise.js +2 -2
@@ -0,0 +1,10 @@
1
+ import type { GenerateOptions, z } from 'genkit';
2
+ import type { SchemaTestable } from '../../schema/index.js';
3
+ import type { TypedOmit } from '../../types/types.js';
4
+ export type TstdlGenkitGenerationOptions<T, O extends z.ZodTypeAny> = TypedOmit<GenerateOptions<z.ZodType<NoInfer<T>>, O>, 'output'> & {
5
+ output?: TypedOmit<NonNullable<GenerateOptions['output']>, 'schema'> & {
6
+ schema?: SchemaTestable<T>;
7
+ };
8
+ };
9
+ export declare function convertToGenkitSchema<T>(schema: SchemaTestable<T>): z.ZodType<T>;
10
+ export declare function genkitGenerationOptions<T, O extends z.ZodTypeAny>(options: TstdlGenkitGenerationOptions<T, O>): GenerateOptions<z.ZodType<T>, z.ZodType<O>>;
@@ -0,0 +1,14 @@
1
+ import { convertToZodV3Schema } from '../../schema/converters/zod-v3-converter.js';
2
+ import { isDefined } from '../../utils/type-guards.js';
3
+ export function convertToGenkitSchema(schema) {
4
+ return convertToZodV3Schema(schema); // eslint-disable-line @typescript-eslint/no-unsafe-return
5
+ }
6
+ export function genkitGenerationOptions(options) {
7
+ return {
8
+ ...options,
9
+ output: {
10
+ ...options.output,
11
+ schema: isDefined(options.output?.schema) ? convertToGenkitSchema(options.output.schema) : undefined,
12
+ },
13
+ };
14
+ }
@@ -0,0 +1,2 @@
1
+ export * from './helpers.js';
2
+ export * from './module.js';
@@ -0,0 +1,2 @@
1
+ export * from './helpers.js';
2
+ export * from './module.js';
@@ -0,0 +1,35 @@
1
+ import { vertexAI } from '@genkit-ai/google-genai';
2
+ import { type Genkit, type GenkitOptions } from 'genkit';
3
+ /**
4
+ * Options for configuring the AI Module.
5
+ */
6
+ export declare class GenkitModuleOptions {
7
+ /** Gemini API specific options. */
8
+ gemini?: {
9
+ /** Gemini API key */
10
+ apiKey?: string;
11
+ };
12
+ /** Vertex AI specific options. If provided, the service will use Vertex AI endpoints. */
13
+ vertex?: {
14
+ /** Google Cloud API key */
15
+ apiKey?: string;
16
+ /** Google Cloud projectId */
17
+ projectId: string;
18
+ /** Google Cloud region */
19
+ location: string;
20
+ /** Path to the Google Cloud credentials file */
21
+ keyFile?: string;
22
+ };
23
+ /** Plugins to register automatically */
24
+ plugins?: GenkitOptions['plugins'];
25
+ /** Default Genkit options */
26
+ options?: Omit<GenkitOptions, 'plugins'>;
27
+ }
28
+ /**
29
+ * Configures the {@link AiService}.
30
+ * @param options The configuration options for the AI services.
31
+ */
32
+ export declare function configureGenkit(options: GenkitModuleOptions): void;
33
+ export declare function injectGenkit(options?: GenkitOptions): Genkit;
34
+ declare const _injectModel: typeof vertexAI.model;
35
+ export { _injectModel as injectModel };
@@ -0,0 +1,56 @@
1
+ import { googleAI, vertexAI } from '@genkit-ai/google-genai';
2
+ import { genkit } from 'genkit';
3
+ import { inject } from '../../injector/inject.js';
4
+ import { Injector } from '../../injector/injector.js';
5
+ import { isDefined, isNotNull } from '../../utils/type-guards.js';
6
+ /**
7
+ * Options for configuring the AI Module.
8
+ */
9
+ export class GenkitModuleOptions {
10
+ /** Gemini API specific options. */
11
+ gemini;
12
+ /** Vertex AI specific options. If provided, the service will use Vertex AI endpoints. */
13
+ vertex;
14
+ /** Plugins to register automatically */
15
+ plugins;
16
+ /** Default Genkit options */
17
+ options;
18
+ }
19
+ /**
20
+ * Configures the {@link AiService}.
21
+ * @param options The configuration options for the AI services.
22
+ */
23
+ export function configureGenkit(options) {
24
+ Injector.register(GenkitModuleOptions, { useValue: options });
25
+ }
26
+ export function injectGenkit(options) {
27
+ const { vertex, gemini, ...moduleOptions } = inject(GenkitModuleOptions, undefined, { optional: true }) ?? {};
28
+ const vertexPlugin = isDefined(vertex)
29
+ ? vertexAI({
30
+ apiKey: vertex.apiKey,
31
+ location: vertex.location,
32
+ projectId: vertex.projectId,
33
+ googleAuth: isDefined(vertex.keyFile) ? { keyFile: vertex.keyFile } : undefined,
34
+ })
35
+ : null;
36
+ const geminiPlugin = isDefined(gemini)
37
+ ? googleAI({ apiKey: gemini.apiKey })
38
+ : null;
39
+ return genkit({
40
+ ...moduleOptions.options,
41
+ ...options,
42
+ plugins: [
43
+ geminiPlugin,
44
+ vertexPlugin,
45
+ ...(moduleOptions.plugins ?? []),
46
+ ...(options?.plugins ?? []),
47
+ ].filter(isNotNull),
48
+ });
49
+ }
50
+ function injectModel(...args) {
51
+ const moduleOptions = inject(GenkitModuleOptions, undefined, { optional: true }) ?? {};
52
+ const provider = isDefined(moduleOptions.vertex) ? vertexAI : googleAI;
53
+ return provider.model(...args);
54
+ }
55
+ const _injectModel = injectModel;
56
+ export { _injectModel as injectModel };
package/ai/index.d.ts CHANGED
@@ -3,4 +3,5 @@ export * from './ai-session.js';
3
3
  export * from './ai.service.js';
4
4
  export * from './functions.js';
5
5
  export * from './module.js';
6
+ export * from './prompts/index.js';
6
7
  export * from './types.js';
package/ai/index.js CHANGED
@@ -3,4 +3,5 @@ export * from './ai-session.js';
3
3
  export * from './ai.service.js';
4
4
  export * from './functions.js';
5
5
  export * from './module.js';
6
+ export * from './prompts/index.js';
6
7
  export * from './types.js';
@@ -0,0 +1,15 @@
1
+ import type { Json } from '../../types/types.js';
2
+ /**
3
+ * Formats objects and arrays for AI context. Requires values to be primitive types (or arrays of primitive types).
4
+ * Nesting of arrays is only supported one level deep and only recommended for a short list of items.
5
+ * If keys are not provided, all supported properties will be included. In case of arrays of objects, the keys of the first object will be used.
6
+ * @param data data to format
7
+ * @param dataTypeName name of the data type (e.g., "document", "users")
8
+ * @param keys keys to include in the output; can be property names or tuples of [property name, value extractor function]
9
+ * @returns formatted string representation of the data
10
+ */
11
+ /**
12
+ * Format data as TOON string for AI context.
13
+ * @param data data to format
14
+ */
15
+ export declare function formatData(data: Json): string;
@@ -0,0 +1,17 @@
1
+ import { encode } from '@toon-format/toon';
2
+ /**
3
+ * Formats objects and arrays for AI context. Requires values to be primitive types (or arrays of primitive types).
4
+ * Nesting of arrays is only supported one level deep and only recommended for a short list of items.
5
+ * If keys are not provided, all supported properties will be included. In case of arrays of objects, the keys of the first object will be used.
6
+ * @param data data to format
7
+ * @param dataTypeName name of the data type (e.g., "document", "users")
8
+ * @param keys keys to include in the output; can be property names or tuples of [property name, value extractor function]
9
+ * @returns formatted string representation of the data
10
+ */
11
+ /**
12
+ * Format data as TOON string for AI context.
13
+ * @param data data to format
14
+ */
15
+ export function formatData(data) {
16
+ return encode(data, { keyFolding: 'safe', indent: 2 });
17
+ }
@@ -0,0 +1,3 @@
1
+ export * from './format.js';
2
+ export * from './instructions-formatter.js';
3
+ export * from './instructions.js';
@@ -0,0 +1,3 @@
1
+ export * from './format.js';
2
+ export * from './instructions-formatter.js';
3
+ export * from './instructions.js';
@@ -0,0 +1,25 @@
1
+ export type ListStyle = 'sections' | 'ordered' | 'unordered';
2
+ type InstructionsListContent = string[] | Instructions;
3
+ export type InstructionsList = {
4
+ style: ListStyle;
5
+ instruction?: string;
6
+ items: InstructionsListContent;
7
+ };
8
+ export type Instructions = {
9
+ [key: string]: string | string[] | InstructionsList | Instructions;
10
+ };
11
+ export declare function sections(items: InstructionsListContent): InstructionsList;
12
+ export declare function sections(instruction: string, items: InstructionsListContent): InstructionsList;
13
+ export declare function orderedList(items: InstructionsListContent): InstructionsList;
14
+ export declare function orderedList(instruction: string, items: InstructionsListContent): InstructionsList;
15
+ export declare function unorderedList(items: InstructionsListContent): InstructionsList;
16
+ export declare function unorderedList(instruction: string, items: InstructionsListContent): InstructionsList;
17
+ /**
18
+ * Formats instructions into a string representation suitable for AI prompts.
19
+ * @param node
20
+ * @param options
21
+ */
22
+ export declare function formatInstructions(node: Instructions | InstructionsList | string[], options?: {
23
+ initialDepth?: number;
24
+ }): string;
25
+ export {};
@@ -0,0 +1,166 @@
1
+ import { hasOwnProperty, objectEntries } from '../../utils/object/object.js';
2
+ import { assertDefined, isArray, isDefined, isObject, isString } from '../../utils/type-guards.js';
3
+ // --- Factories ---
4
+ function list(style, instructionOrItems, itemsOrNothing) {
5
+ const instruction = isString(instructionOrItems) ? instructionOrItems : undefined;
6
+ const items = isString(instructionOrItems) ? itemsOrNothing : instructionOrItems;
7
+ assertDefined(items, 'Instructions list is empty.');
8
+ return { style, instruction, items };
9
+ }
10
+ export function sections(instructionOrItems, itemsOrNothing) {
11
+ return list('sections', instructionOrItems, itemsOrNothing);
12
+ }
13
+ export function orderedList(instructionOrItems, itemsOrNothing) {
14
+ return list('ordered', instructionOrItems, itemsOrNothing);
15
+ }
16
+ export function unorderedList(instructionOrItems, itemsOrNothing) {
17
+ return list('unordered', instructionOrItems, itemsOrNothing);
18
+ }
19
+ // --- Type Guards ---
20
+ function isInstructionsList(obj) {
21
+ return isObject(obj) && hasOwnProperty(obj, 'style') && hasOwnProperty(obj, 'items');
22
+ }
23
+ // --- Formatter Logic ---
24
+ const INDENT_SIZE = 2;
25
+ function getPrefix(style, index, sectionDepth) {
26
+ switch (style) {
27
+ case 'ordered':
28
+ return `${index + 1}. `;
29
+ case 'unordered':
30
+ return '- ';
31
+ case 'sections':
32
+ return '#'.repeat(Math.max(1, sectionDepth)) + ' ';
33
+ default:
34
+ return '';
35
+ }
36
+ }
37
+ /**
38
+ * Formats a string that might span multiple lines.
39
+ * It calculates the hanging indent based on the length of the prefix used on the first line.
40
+ */
41
+ function formatWithHangingIndent(text, baseIndent, prefix) {
42
+ const lines = text.split('\n');
43
+ if (lines.length == 0) {
44
+ return '';
45
+ }
46
+ const firstLine = `${baseIndent}${prefix}${lines[0]}`;
47
+ if (lines.length == 1) {
48
+ return firstLine;
49
+ }
50
+ // Create a spacer that exactly matches the visual length of " 1. " or " - "
51
+ const hangingSpacer = ' '.repeat(baseIndent.length + prefix.length);
52
+ return [
53
+ firstLine,
54
+ ...lines.slice(1).map((line) => `${hangingSpacer}${line}`),
55
+ ].join('\n');
56
+ }
57
+ /**
58
+ * Main recursive formatter.
59
+ */
60
+ function processNode(node, context) {
61
+ // 1. Unwrap InstructionsList (The Wrapper)
62
+ // If the node is a wrapper, we adopt its style and instruction, then process its items.
63
+ if (isInstructionsList(node)) {
64
+ // Note: We don't print the "instruction" here (e.g., "Use Markdown").
65
+ // If this Wrapper is a root node, the instruction is usually printed by the caller or ignored.
66
+ // If this Wrapper is a value of a key, the key printer handles the instruction.
67
+ // However, if we have a "Root Wrapper" with an instruction (rare in your example), handle it:
68
+ const header = node.instruction ? `${node.instruction}\n` : '';
69
+ // Determine next context
70
+ const nextContext = {
71
+ indentDepth: context.indentDepth, // Wrappers don't indent themselves, their content does
72
+ style: node.style,
73
+ sectionDepth: node.style == 'sections' ? context.sectionDepth : context.sectionDepth, // Section depth increments internally
74
+ };
75
+ return header + processNode(node.items, nextContext);
76
+ }
77
+ // Common Constants for this level
78
+ const isSection = context.style == 'sections';
79
+ const currentBaseIndent = ' '.repeat(isSection ? 0 : context.indentDepth * INDENT_SIZE);
80
+ const separator = isSection ? '\n\n' : '\n';
81
+ // 2. Handle Arrays (Simple Lists)
82
+ if (isArray(node)) {
83
+ return node.map((item, index) => {
84
+ const prefix = getPrefix(context.style, index, context.sectionDepth);
85
+ return formatWithHangingIndent(item, currentBaseIndent, prefix);
86
+ }).join(separator);
87
+ }
88
+ // 3. Handle Objects (Key-Value Maps)
89
+ return objectEntries(node).map(([key, value], index) => {
90
+ const prefix = getPrefix(context.style, index, context.sectionDepth);
91
+ // Detect if the Value is a Wrapper (e.g. `Key: ordered(...)`)
92
+ // This allows us to pull the wrapper's "instruction" up to the Key line.
93
+ const isValueWrapper = isInstructionsList(value);
94
+ const effectiveValue = isValueWrapper ? value.items : value;
95
+ const instruction = (isValueWrapper && isDefined(value.instruction)) ? ` ${value.instruction}` : '';
96
+ const childStyle = isValueWrapper ? value.style : (isSection ? 'unordered' : 'unordered');
97
+ // Formatting the Header Line (The Key)
98
+ let headerLine = '';
99
+ if (isSection) {
100
+ // Header format: "# Key" or "# Key\n\nInstruction"
101
+ const instructionPart = (instruction.length > 0) ? `\n\n${instruction.trim()}` : '';
102
+ headerLine = `${currentBaseIndent}${prefix}${key}${instructionPart}`;
103
+ }
104
+ else {
105
+ // List format: "- **Key:**" or "- **Key:** Instruction"
106
+ const keyPart = `**${key}:**`;
107
+ headerLine = `${currentBaseIndent}${prefix}${keyPart}${instruction}`;
108
+ }
109
+ // Determine context for the children
110
+ // If we are a Section, children reset indent to 0.
111
+ // If we are a List, children indent + 1.
112
+ const nextIndentDepth = isSection ? 0 : context.indentDepth + 1;
113
+ // If the child acts as a section (Wrapper was `sections(...)`), increment H-level.
114
+ const nextSectionDepth = (isValueWrapper && value.style == 'sections')
115
+ ? context.sectionDepth + 1
116
+ : context.sectionDepth;
117
+ // Recurse
118
+ // If the value is a simple string, we print it inline if possible, or block if it's long?
119
+ // Your requirement: Strings in objects are usually descriptions.
120
+ if (isString(effectiveValue)) {
121
+ // If it's a string, we treat it as content on the SAME line for lists (via hanging indent logic),
122
+ // or a new paragraph for Sections.
123
+ if (isSection) {
124
+ // Section: Header \n\n Content
125
+ return `${headerLine}\n\n${effectiveValue.trim()}`;
126
+ }
127
+ else {
128
+ // List: "- **Key:** Value"
129
+ // We need to construct the full string to calculate hanging indent correctly.
130
+ // headerLine already contains indentation + prefix + key.
131
+ // We strip the indentation to feed it into the formatting helper effectively.
132
+ const fullLine = `${headerLine} ${effectiveValue}`.trim();
133
+ return formatWithHangingIndent(fullLine, currentBaseIndent, '');
134
+ }
135
+ }
136
+ // If Value is Object/Array/Wrapper
137
+ const body = processNode(effectiveValue, {
138
+ indentDepth: nextIndentDepth,
139
+ style: childStyle,
140
+ sectionDepth: nextSectionDepth,
141
+ });
142
+ const bodySeparator = isSection ? '\n\n' : '\n';
143
+ // Edge case: If it's a section, we constructed the header, now append body.
144
+ // If it's a list, the header line serves as the parent item.
145
+ return `${headerLine}${bodySeparator}${body}`;
146
+ }).join(separator);
147
+ }
148
+ /**
149
+ * Formats instructions into a string representation suitable for AI prompts.
150
+ * @param node
151
+ * @param options
152
+ */
153
+ export function formatInstructions(node, options = {}) {
154
+ // Heuristic: If passing a raw object, assume it's a Root Section unless specified otherwise.
155
+ // If passing a Wrapper, the Wrapper dictates the style.
156
+ const initialStyle = isInstructionsList(node)
157
+ ? node.style
158
+ : isArray(node)
159
+ ? 'unordered'
160
+ : 'sections';
161
+ return processNode(node, {
162
+ indentDepth: options.initialDepth ?? 0,
163
+ sectionDepth: 1,
164
+ style: initialStyle,
165
+ }).trim();
166
+ }
@@ -0,0 +1,3 @@
1
+ export declare const jsonOutputInstructions: {
2
+ 'JSON Output': import("./instructions-formatter.js").InstructionsList;
3
+ };
@@ -0,0 +1,8 @@
1
+ import { unorderedList } from './instructions-formatter.js';
2
+ export const jsonOutputInstructions = {
3
+ 'JSON Output': unorderedList({
4
+ 'Schema Compliance': 'Generate valid JSON that strictly matches the provided schema.',
5
+ 'Nullable fields with missing data': 'Must be set to literal `null`.',
6
+ 'Optional fields with missing data': 'Omit the key entirely (sparse JSON).',
7
+ }),
8
+ };
@@ -29,6 +29,8 @@ export declare class DocumentFileService extends Transactional {
29
29
  getContent(document: Document): Promise<Uint8Array>;
30
30
  getContentStream(document: Document): ReadableStream<Uint8Array>;
31
31
  getContentUrl(document: Document, download?: boolean): Promise<string>;
32
+ /** Gets the underlying object storage object for the document file */
33
+ getObject(document: Document): Promise<import("../../../object-storage/index.js").ObjectStorageObject>;
32
34
  getPreview(document: Document, page?: number): Promise<Uint8Array>;
33
35
  getPreviewStream(document: Document, page?: number): ReadableStream<Uint8Array>;
34
36
  getPreviewUrl(document: Document, page?: number): Promise<string>;
@@ -56,8 +56,6 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
56
56
  var e = new Error(message);
57
57
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
58
58
  });
59
- var _a;
60
- var DocumentFileService_1;
61
59
  import sharp, {} from 'sharp';
62
60
  import { match } from 'ts-pattern';
63
61
  import { AiService } from '../../../ai/ai.service.js';
@@ -66,7 +64,6 @@ import { NotImplementedError } from '../../../errors/not-implemented.error.js';
66
64
  import { getMimeType, getMimeTypeExtensions, mimeTypes } from '../../../file/index.js';
67
65
  import { TemporaryFile } from '../../../file/server/index.js';
68
66
  import { inject } from '../../../injector/inject.js';
69
- import { Logger } from '../../../logger/logger.js';
70
67
  import { ObjectStorage } from '../../../object-storage/index.js';
71
68
  import { Transactional } from '../../../orm/server/index.js';
72
69
  import { pdfToImage } from '../../../pdf/index.js';
@@ -80,13 +77,12 @@ import { millisecondsPerMinute, secondsPerMinute } from '../../../utils/units.js
80
77
  import { Document } from '../../models/index.js';
81
78
  import { DocumentManagementConfiguration } from '../module.js';
82
79
  import { DocumentManagementSingleton } from './singleton.js';
83
- let DocumentFileService = DocumentFileService_1 = class DocumentFileService extends Transactional {
80
+ let DocumentFileService = class DocumentFileService extends Transactional {
84
81
  #configuration = inject(DocumentManagementConfiguration);
85
82
  #aiService = inject(AiService);
86
83
  #fileObjectStorage = inject(ObjectStorage, this.#configuration.fileObjectStorageModule);
87
84
  #filePreviewObjectStorage = inject(ObjectStorage, this.#configuration.filePreviewObjectStorageModule);
88
85
  #fileUploadObjectStorage = inject(ObjectStorage, { module: this.#configuration.fileUploadObjectStorageModule, configuration: { lifecycle: { expiration: { after: 5 * secondsPerMinute } } } });
89
- #logger = inject(Logger, DocumentFileService_1.name);
90
86
  #aiFilePartCache = new Map();
91
87
  /**
92
88
  * Initiates a file upload
@@ -145,6 +141,11 @@ let DocumentFileService = DocumentFileService_1 = class DocumentFileService exte
145
141
  async getContentUrl(document, download = false) {
146
142
  return await this.getDocumentFileContentObjectUrl(document, document.title ?? document.id, download);
147
143
  }
144
+ /** Gets the underlying object storage object for the document file */
145
+ async getObject(document) {
146
+ const objectKey = getObjectKey(document.id);
147
+ return await this.#fileObjectStorage.getObject(objectKey);
148
+ }
148
149
  async getPreview(document, page = 1) {
149
150
  const objectKey = getObjectKey(document.id);
150
151
  await this.createPreviewIfNotExists(document, page);
@@ -197,12 +198,12 @@ let DocumentFileService = DocumentFileService_1 = class DocumentFileService exte
197
198
  const content = await this.#fileObjectStorage.getContent(key);
198
199
  const image = await match(document.mimeType)
199
200
  .with('application/pdf', async () => {
200
- const imageBytes = await pdfToImage(content, page, 768, 'jpeg');
201
+ const imageBytes = await pdfToImage(content, page, 768, 'png');
201
202
  return await imageToPreview(imageBytes);
202
203
  })
203
204
  .with('image/*', async () => await imageToPreview(content))
204
205
  .otherwise(() => { throw new NotImplementedError('Preview generation is not implemented for this file type.'); });
205
- await this.#filePreviewObjectStorage.uploadObject(key, image, { contentLength: image.length, contentType: 'image/jpeg' });
206
+ await this.#filePreviewObjectStorage.uploadObject(key, image, { contentLength: image.length, contentType: 'image/webp' });
206
207
  }
207
208
  }
208
209
  async getDocumentFileContentObjectUrl(document, title, download) {
@@ -216,7 +217,7 @@ let DocumentFileService = DocumentFileService_1 = class DocumentFileService exte
216
217
  });
217
218
  }
218
219
  };
219
- DocumentFileService = DocumentFileService_1 = __decorate([
220
+ DocumentFileService = __decorate([
220
221
  DocumentManagementSingleton()
221
222
  ], DocumentFileService);
222
223
  export { DocumentFileService };
@@ -233,6 +234,6 @@ async function imageToPreview(input) {
233
234
  withoutEnlargement: true,
234
235
  fastShrinkOnLoad: false,
235
236
  })
236
- .toFormat('jpeg', { quality: 75 })
237
+ .toFormat('webp', { quality: 75 })
237
238
  .toBuffer();
238
239
  }
@@ -15,6 +15,7 @@ export type DocumentInformationExtractionResult = {
15
15
  };
16
16
  export declare class DocumentManagementAiService {
17
17
  #private;
18
+ extractDocumentContent(tenantId: string, documentId: string): Promise<string>;
18
19
  classifyDocumentType(tenantId: string, documentId: string): Promise<string>;
19
20
  extractDocumentInformation(tenantId: string, documentId: string): Promise<DocumentInformationExtractionResult>;
20
21
  findSuitableCollectionsForDocument(document: Document, collectionIds: string[]): Promise<string[]>;