@luzzle/core 0.0.62 → 0.0.63

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 (81) hide show
  1. package/README.md +38 -8
  2. package/dist/src/index.d.ts +2 -2
  3. package/dist/src/index.js +2 -2
  4. package/dist/src/index.js.map +1 -1
  5. package/dist/src/pieces/Piece.js +2 -2
  6. package/dist/src/pieces/Piece.js.map +1 -1
  7. package/dist/src/pieces/index.d.ts +1 -0
  8. package/dist/src/pieces/index.js +1 -0
  9. package/dist/src/pieces/index.js.map +1 -1
  10. package/dist/src/pieces/utils/piece.d.ts +3 -2
  11. package/dist/src/pieces/utils/piece.js +17 -14
  12. package/dist/src/pieces/utils/piece.js.map +1 -1
  13. package/dist/tsconfig.build.tsbuildinfo +1 -0
  14. package/package.json +3 -3
  15. package/dist/src/database/NodeSqliteDialect.test.d.ts +0 -1
  16. package/dist/src/database/NodeSqliteDialect.test.js +0 -104
  17. package/dist/src/database/NodeSqliteDialect.test.js.map +0 -1
  18. package/dist/src/database/client.test.d.ts +0 -1
  19. package/dist/src/database/client.test.js +0 -36
  20. package/dist/src/database/client.test.js.map +0 -1
  21. package/dist/src/database/migrations.test.d.ts +0 -1
  22. package/dist/src/database/migrations.test.js +0 -19
  23. package/dist/src/database/migrations.test.js.map +0 -1
  24. package/dist/src/database/utils.test.d.ts +0 -1
  25. package/dist/src/database/utils.test.js +0 -9
  26. package/dist/src/database/utils.test.js.map +0 -1
  27. package/dist/src/index.test.d.ts +0 -1
  28. package/dist/src/index.test.js +0 -9
  29. package/dist/src/index.test.js.map +0 -1
  30. package/dist/src/lib/ajv.test.d.ts +0 -1
  31. package/dist/src/lib/ajv.test.js +0 -49
  32. package/dist/src/lib/ajv.test.js.map +0 -1
  33. package/dist/src/lib/frontmatter.test.d.ts +0 -1
  34. package/dist/src/lib/frontmatter.test.js +0 -37
  35. package/dist/src/lib/frontmatter.test.js.map +0 -1
  36. package/dist/src/lib/markdown.test.d.ts +0 -1
  37. package/dist/src/lib/markdown.test.js +0 -34
  38. package/dist/src/lib/markdown.test.js.map +0 -1
  39. package/dist/src/llm/google.test.d.ts +0 -1
  40. package/dist/src/llm/google.test.js +0 -253
  41. package/dist/src/llm/google.test.js.map +0 -1
  42. package/dist/src/pieces/Piece.test.d.ts +0 -1
  43. package/dist/src/pieces/Piece.test.js +0 -628
  44. package/dist/src/pieces/Piece.test.js.map +0 -1
  45. package/dist/src/pieces/Pieces.test.d.ts +0 -1
  46. package/dist/src/pieces/Pieces.test.js +0 -325
  47. package/dist/src/pieces/Pieces.test.js.map +0 -1
  48. package/dist/src/pieces/cache.test.d.ts +0 -1
  49. package/dist/src/pieces/cache.test.js +0 -72
  50. package/dist/src/pieces/cache.test.js.map +0 -1
  51. package/dist/src/pieces/item.test.d.ts +0 -1
  52. package/dist/src/pieces/item.test.js +0 -243
  53. package/dist/src/pieces/item.test.js.map +0 -1
  54. package/dist/src/pieces/items.test.d.ts +0 -1
  55. package/dist/src/pieces/items.test.js +0 -103
  56. package/dist/src/pieces/items.test.js.map +0 -1
  57. package/dist/src/pieces/json.schema.test.d.ts +0 -1
  58. package/dist/src/pieces/json.schema.test.js +0 -27
  59. package/dist/src/pieces/json.schema.test.js.map +0 -1
  60. package/dist/src/pieces/manager.test.d.ts +0 -1
  61. package/dist/src/pieces/manager.test.js +0 -55
  62. package/dist/src/pieces/manager.test.js.map +0 -1
  63. package/dist/src/pieces/utils/frontmatter.path.test.d.ts +0 -1
  64. package/dist/src/pieces/utils/frontmatter.path.test.js +0 -319
  65. package/dist/src/pieces/utils/frontmatter.path.test.js.map +0 -1
  66. package/dist/src/pieces/utils/frontmatter.test.d.ts +0 -1
  67. package/dist/src/pieces/utils/frontmatter.test.js +0 -335
  68. package/dist/src/pieces/utils/frontmatter.test.js.map +0 -1
  69. package/dist/src/pieces/utils/markdown.test.d.ts +0 -1
  70. package/dist/src/pieces/utils/markdown.test.js +0 -38
  71. package/dist/src/pieces/utils/markdown.test.js.map +0 -1
  72. package/dist/src/pieces/utils/piece.test.d.ts +0 -1
  73. package/dist/src/pieces/utils/piece.test.js +0 -348
  74. package/dist/src/pieces/utils/piece.test.js.map +0 -1
  75. package/dist/src/storage/fs.test.d.ts +0 -1
  76. package/dist/src/storage/fs.test.js +0 -212
  77. package/dist/src/storage/fs.test.js.map +0 -1
  78. package/dist/test/db.d.ts +0 -3
  79. package/dist/test/db.js +0 -19
  80. package/dist/test/db.js.map +0 -1
  81. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,253 +0,0 @@
1
- import { describe, expect, vi, afterEach, test } from 'vitest';
2
- import { pieceFrontMatterFromPrompt } from './google.js';
3
- import { GoogleGenAI, createPartFromUri, } from '@google/genai';
4
- import { fileTypeFromBuffer, fileTypeFromFile } from 'file-type';
5
- import { readFile } from 'fs/promises';
6
- // Mock schema created locally to remove dependency on piece.fixtures.ts
7
- const makeSchema = (name) => {
8
- return {
9
- type: 'object',
10
- title: name,
11
- properties: {
12
- title: { type: 'string', examples: ['title'] },
13
- keywords: { type: 'string', nullable: true },
14
- },
15
- required: ['title'],
16
- additionalProperties: false,
17
- };
18
- };
19
- vi.mock('@luzzle/core');
20
- vi.mock('file-type');
21
- vi.mock('fs/promises');
22
- vi.mock('@google/genai', () => {
23
- const Gemini = vi.fn();
24
- Gemini.prototype.models = vi.fn();
25
- Gemini.prototype.files = vi.fn();
26
- Gemini.prototype.models.generateContent = vi.fn();
27
- Gemini.prototype.files.upload = vi.fn();
28
- Gemini.prototype.files.get = vi.fn();
29
- return {
30
- GoogleGenAI: Gemini,
31
- HarmCategory: {},
32
- HarmBlockThreshold: {},
33
- createPartFromUri: vi.fn(),
34
- };
35
- });
36
- const mocks = {
37
- generateContent: vi.mocked(GoogleGenAI.prototype.models.generateContent),
38
- uploadFile: vi.mocked(GoogleGenAI.prototype.files.upload),
39
- getFile: vi.mocked(GoogleGenAI.prototype.files.get),
40
- fileTypeFromFile: vi.mocked(fileTypeFromFile),
41
- fileTypeFromBuffer: vi.mocked(fileTypeFromBuffer),
42
- createPartFromUri: vi.mocked(createPartFromUri),
43
- readFile: vi.mocked(readFile),
44
- };
45
- const spies = {};
46
- describe('lib/llm/google.ts', () => {
47
- afterEach(() => {
48
- Object.values(mocks).forEach((mock) => {
49
- mock.mockReset();
50
- });
51
- Object.keys(spies).forEach((key) => {
52
- spies[key].mockRestore();
53
- delete spies[key];
54
- });
55
- });
56
- test('pieceFrontMatterFromPrompt', async () => {
57
- const apiKey = 'apiKey';
58
- const schema = makeSchema('books');
59
- const prompt = 'prompt';
60
- const frontmatter = { field: 'value' };
61
- const responseText = JSON.stringify(frontmatter);
62
- mocks.generateContent.mockResolvedValueOnce({
63
- text: responseText,
64
- });
65
- const generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt);
66
- expect(mocks.generateContent).toHaveBeenCalledTimes(1);
67
- expect(mocks.generateContent).toHaveBeenCalledWith({
68
- contents: expect.arrayContaining([prompt]),
69
- config: expect.any(Object),
70
- model: expect.any(String),
71
- });
72
- expect(generatedFrontmatter).toEqual(frontmatter);
73
- });
74
- test('pieceFrontMatterFromPrompt strips empty fields', async () => {
75
- const apiKey = 'apiKey';
76
- const schema = makeSchema('books');
77
- const prompt = 'prompt';
78
- const frontmatter = { field: 'value', field2: null, field3: undefined };
79
- const responseText = JSON.stringify(frontmatter);
80
- mocks.generateContent.mockResolvedValueOnce({
81
- text: responseText,
82
- });
83
- const generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt);
84
- expect(mocks.generateContent).toHaveBeenCalledTimes(1);
85
- expect(mocks.generateContent).toHaveBeenCalledWith({
86
- contents: expect.arrayContaining([prompt]),
87
- config: expect.any(Object),
88
- model: expect.any(String),
89
- });
90
- expect(generatedFrontmatter).toEqual({ field: 'value' });
91
- });
92
- test('pieceFrontMatterFromPrompt returns on empty result', async () => {
93
- const apiKey = 'apiKey';
94
- const schema = makeSchema('books');
95
- const prompt = 'prompt';
96
- const responseText = undefined;
97
- mocks.generateContent.mockResolvedValueOnce({
98
- text: responseText,
99
- });
100
- const generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt);
101
- expect(mocks.generateContent).toHaveBeenCalledTimes(1);
102
- expect(mocks.generateContent).toHaveBeenCalledWith({
103
- contents: expect.arrayContaining([prompt]),
104
- config: expect.any(Object),
105
- model: expect.any(String),
106
- });
107
- expect(generatedFrontmatter).toEqual({});
108
- });
109
- test('generatePieceFrontmatter with a binary file', async () => {
110
- const apiKey = 'apiKey';
111
- const schema = makeSchema('books');
112
- const prompt = 'prompt';
113
- const file = '/path/to/file.pdf';
114
- const uri = 'gs://another/path/to/file.pdf';
115
- const name = 'file.pdf';
116
- const mimeType = 'application/pdf';
117
- const frontmatter = { field: 'value' };
118
- const responseText = JSON.stringify(frontmatter);
119
- const fileContent = 'fileContent';
120
- vi.useFakeTimers();
121
- mocks.generateContent.mockResolvedValueOnce({
122
- text: responseText,
123
- });
124
- mocks.uploadFile.mockResolvedValue({ name, uri, mimeType });
125
- mocks.getFile.mockResolvedValueOnce({ state: 'PROCESSING' });
126
- mocks.getFile.mockResolvedValueOnce({ uri, mimeType, state: 'ACTIVE' });
127
- mocks.fileTypeFromFile.mockResolvedValueOnce({ mime: mimeType, ext: 'pdf' });
128
- mocks.createPartFromUri.mockReturnValue(fileContent);
129
- vi.runAllTimersAsync();
130
- const generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt, [file]);
131
- expect(mocks.uploadFile).toHaveBeenCalledWith({ file, config: { mimeType } });
132
- expect(mocks.getFile).toHaveBeenCalledWith({ name });
133
- expect(mocks.createPartFromUri).toHaveBeenCalledTimes(1);
134
- expect(mocks.generateContent).toHaveBeenCalledTimes(1);
135
- expect(mocks.generateContent).toHaveBeenCalledWith({
136
- contents: expect.arrayContaining([prompt, fileContent]),
137
- config: expect.any(Object),
138
- model: expect.any(String),
139
- });
140
- expect(generatedFrontmatter).toEqual(frontmatter);
141
- vi.useRealTimers();
142
- });
143
- test('generatePieceFrontmatter with a text file', async () => {
144
- const apiKey = 'apiKey';
145
- const schema = makeSchema('books');
146
- const prompt = 'prompt';
147
- const file = '/path/to/file.html';
148
- const frontmatter = { field: 'value' };
149
- const responseText = JSON.stringify(frontmatter);
150
- const fileContent = 'fileContent';
151
- mocks.generateContent.mockResolvedValueOnce({
152
- text: responseText,
153
- });
154
- mocks.fileTypeFromFile.mockResolvedValueOnce(undefined);
155
- mocks.readFile.mockResolvedValueOnce(fileContent);
156
- const generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt, [file]);
157
- expect(mocks.generateContent).toHaveBeenCalledTimes(1);
158
- expect(mocks.generateContent).toHaveBeenCalledWith({
159
- contents: expect.arrayContaining([prompt, expect.stringContaining(fileContent)]),
160
- config: expect.any(Object),
161
- model: expect.any(String),
162
- });
163
- expect(generatedFrontmatter).toEqual(frontmatter);
164
- vi.useRealTimers();
165
- });
166
- test('generatePieceFrontmatter with a text Buffer', async () => {
167
- const apiKey = 'apiKey';
168
- const schema = makeSchema('books');
169
- const prompt = 'prompt';
170
- const frontmatter = { field: 'value' };
171
- const responseText = JSON.stringify(frontmatter);
172
- const buffer = Buffer.from('buffer data');
173
- mocks.generateContent.mockResolvedValueOnce({
174
- text: responseText,
175
- });
176
- mocks.fileTypeFromBuffer.mockResolvedValueOnce(undefined);
177
- const generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt, [buffer]);
178
- expect(mocks.generateContent).toHaveBeenCalledTimes(1);
179
- expect(mocks.generateContent).toHaveBeenCalledWith({
180
- contents: expect.arrayContaining([prompt, expect.stringContaining(buffer.toString())]),
181
- config: expect.any(Object),
182
- model: expect.any(String),
183
- });
184
- expect(generatedFrontmatter).toEqual(frontmatter);
185
- });
186
- test('generatePieceFrontmatter with a binary Buffer', async () => {
187
- const apiKey = 'apiKey';
188
- const schema = makeSchema('books');
189
- const prompt = 'prompt';
190
- const name = 'file.pdf';
191
- const uri = 'gs://another/path/to/file.pdf';
192
- const mimeType = 'application/pdf';
193
- const frontmatter = { field: 'value' };
194
- const responseText = JSON.stringify(frontmatter);
195
- const buffer = Buffer.from('buffer data');
196
- const blob = new Blob([buffer]);
197
- const fileContent = 'fileContent';
198
- mocks.generateContent.mockResolvedValueOnce({
199
- text: responseText,
200
- });
201
- mocks.uploadFile.mockResolvedValue({ name, uri, mimeType });
202
- mocks.getFile.mockResolvedValue({ uri, mimeType, state: 'ACTIVE' });
203
- mocks.fileTypeFromBuffer.mockResolvedValueOnce({ mime: mimeType, ext: 'pdf' });
204
- mocks.createPartFromUri.mockReturnValue(fileContent);
205
- const generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt, [buffer]);
206
- expect(mocks.uploadFile).toHaveBeenCalledWith({ file: blob, config: { mimeType } });
207
- expect(mocks.getFile).toHaveBeenCalledWith({ name });
208
- expect(mocks.generateContent).toHaveBeenCalledTimes(1);
209
- expect(mocks.generateContent).toHaveBeenCalledWith({
210
- contents: expect.arrayContaining([prompt, fileContent]),
211
- config: expect.any(Object),
212
- model: expect.any(String),
213
- });
214
- expect(generatedFrontmatter).toEqual(frontmatter);
215
- });
216
- test('generatePieceFrontmatter binary file fails to process upload', async () => {
217
- const apiKey = 'apiKey';
218
- const schema = makeSchema('books');
219
- const prompt = 'prompt';
220
- const file = '/path/to/file.pdf';
221
- const name = 'file.pdf';
222
- const mimeType = 'application/pdf';
223
- const frontmatter = { field: 'value' };
224
- const responseText = JSON.stringify(frontmatter);
225
- mocks.generateContent.mockResolvedValueOnce({
226
- text: responseText,
227
- });
228
- mocks.uploadFile.mockResolvedValue({ name, state: 'FAILED' });
229
- mocks.getFile.mockResolvedValue({});
230
- mocks.fileTypeFromFile.mockResolvedValueOnce({ mime: mimeType, ext: 'pdf' });
231
- const generating = pieceFrontMatterFromPrompt(apiKey, schema, prompt, [file]);
232
- expect(generating).rejects.toThrowError();
233
- });
234
- test('generatePieceFrontmatter file fails to extract', async () => {
235
- const apiKey = 'apiKey';
236
- const schema = makeSchema('books');
237
- const prompt = 'prompt';
238
- const file = '/path/to/file.pdf';
239
- const name = 'file.pdf';
240
- const mimeType = 'application/pdf';
241
- const frontmatter = { field: 'value' };
242
- const responseText = JSON.stringify(frontmatter);
243
- mocks.generateContent.mockResolvedValueOnce({
244
- text: responseText,
245
- });
246
- mocks.uploadFile.mockResolvedValue({ name, uri: undefined });
247
- mocks.getFile.mockResolvedValue({});
248
- mocks.fileTypeFromFile.mockResolvedValueOnce({ mime: mimeType, ext: 'pdf' });
249
- const generating = pieceFrontMatterFromPrompt(apiKey, schema, prompt, [file]);
250
- expect(generating).rejects.toThrowError();
251
- });
252
- });
253
- //# sourceMappingURL=google.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"google.test.js","sourceRoot":"","sources":["../../../src/llm/google.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, vi, afterEach, test, MockInstance } from 'vitest'\nimport { pieceFrontMatterFromPrompt } from './google.js'\nimport {\n\tGoogleGenAI,\n\tPart,\n\tcreatePartFromUri,\n\tGenerateContentResponse,\n\tFileState,\n} from '@google/genai'\nimport { fileTypeFromBuffer, fileTypeFromFile } from 'file-type'\nimport { readFile } from 'fs/promises'\nimport { JSONSchemaType } from 'ajv'\nimport { PieceFrontmatter } from '../pieces/index.js'\n\n// Mock schema created locally to remove dependency on piece.fixtures.ts\nconst makeSchema = (\n\tname: string\n): JSONSchemaType<PieceFrontmatter> => {\n\treturn {\n\t\ttype: 'object',\n\t\ttitle: name,\n\t\tproperties: {\n\t\t\ttitle: { type: 'string', examples: ['title'] },\n\t\t\tkeywords: { type: 'string', nullable: true },\n\t\t},\n\t\trequired: ['title'],\n\t\tadditionalProperties: false,\n\t} as unknown as JSONSchemaType<PieceFrontmatter>\n}\n\nvi.mock('@luzzle/core')\nvi.mock('file-type')\nvi.mock('fs/promises')\nvi.mock('@google/genai', () => {\n\tconst Gemini = vi.fn()\n\n\tGemini.prototype.models = vi.fn()\n\tGemini.prototype.files = vi.fn()\n\tGemini.prototype.models.generateContent = vi.fn()\n\tGemini.prototype.files.upload = vi.fn()\n\tGemini.prototype.files.get = vi.fn()\n\n\treturn {\n\t\tGoogleGenAI: Gemini,\n\t\tHarmCategory: {},\n\t\tHarmBlockThreshold: {},\n\t\tcreatePartFromUri: vi.fn(),\n\t}\n})\n\nconst mocks = {\n\tgenerateContent: vi.mocked(GoogleGenAI.prototype.models.generateContent),\n\tuploadFile: vi.mocked(GoogleGenAI.prototype.files.upload),\n\tgetFile: vi.mocked(GoogleGenAI.prototype.files.get),\n\tfileTypeFromFile: vi.mocked(fileTypeFromFile),\n\tfileTypeFromBuffer: vi.mocked(fileTypeFromBuffer),\n\tcreatePartFromUri: vi.mocked(createPartFromUri),\n\treadFile: vi.mocked(readFile),\n}\n\nconst spies: { [key: string]: MockInstance } = {}\n\ndescribe('lib/llm/google.ts', () => {\n\tafterEach(() => {\n\t\tObject.values(mocks).forEach((mock) => {\n\t\t\tmock.mockReset()\n\t\t})\n\n\t\tObject.keys(spies).forEach((key) => {\n\t\t\tspies[key].mockRestore()\n\t\t\tdelete spies[key]\n\t\t})\n\t})\n\n\ttest('pieceFrontMatterFromPrompt', async () => {\n\t\tconst apiKey = 'apiKey'\n\t\tconst schema = makeSchema('books')\n\t\tconst prompt = 'prompt'\n\t\tconst frontmatter = { field: 'value' }\n\t\tconst responseText = JSON.stringify(frontmatter)\n\n\t\tmocks.generateContent.mockResolvedValueOnce({\n\t\t\ttext: responseText,\n\t\t} as GenerateContentResponse)\n\n\t\tconst generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt)\n\n\t\texpect(mocks.generateContent).toHaveBeenCalledTimes(1)\n\t\texpect(mocks.generateContent).toHaveBeenCalledWith({\n\t\t\tcontents: expect.arrayContaining([prompt]),\n\t\t\tconfig: expect.any(Object),\n\t\t\tmodel: expect.any(String),\n\t\t})\n\t\texpect(generatedFrontmatter).toEqual(frontmatter)\n\t})\n\n\ttest('pieceFrontMatterFromPrompt strips empty fields', async () => {\n\t\tconst apiKey = 'apiKey'\n\t\tconst schema = makeSchema('books')\n\t\tconst prompt = 'prompt'\n\t\tconst frontmatter = { field: 'value', field2: null, field3: undefined }\n\t\tconst responseText = JSON.stringify(frontmatter)\n\n\t\tmocks.generateContent.mockResolvedValueOnce({\n\t\t\ttext: responseText,\n\t\t} as GenerateContentResponse)\n\n\t\tconst generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt)\n\n\t\texpect(mocks.generateContent).toHaveBeenCalledTimes(1)\n\t\texpect(mocks.generateContent).toHaveBeenCalledWith({\n\t\t\tcontents: expect.arrayContaining([prompt]),\n\t\t\tconfig: expect.any(Object),\n\t\t\tmodel: expect.any(String),\n\t\t})\n\t\texpect(generatedFrontmatter).toEqual({ field: 'value' })\n\t})\n\n\ttest('pieceFrontMatterFromPrompt returns on empty result', async () => {\n\t\tconst apiKey = 'apiKey'\n\t\tconst schema = makeSchema('books')\n\t\tconst prompt = 'prompt'\n\t\tconst responseText = undefined\n\n\t\tmocks.generateContent.mockResolvedValueOnce({\n\t\t\ttext: responseText,\n\t\t} as GenerateContentResponse)\n\n\t\tconst generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt)\n\n\t\texpect(mocks.generateContent).toHaveBeenCalledTimes(1)\n\t\texpect(mocks.generateContent).toHaveBeenCalledWith({\n\t\t\tcontents: expect.arrayContaining([prompt]),\n\t\t\tconfig: expect.any(Object),\n\t\t\tmodel: expect.any(String),\n\t\t})\n\t\texpect(generatedFrontmatter).toEqual({})\n\t})\n\n\ttest('generatePieceFrontmatter with a binary file', async () => {\n\t\tconst apiKey = 'apiKey'\n\t\tconst schema = makeSchema('books')\n\t\tconst prompt = 'prompt'\n\t\tconst file = '/path/to/file.pdf'\n\t\tconst uri = 'gs://another/path/to/file.pdf'\n\t\tconst name = 'file.pdf'\n\t\tconst mimeType = 'application/pdf'\n\t\tconst frontmatter = { field: 'value' }\n\t\tconst responseText = JSON.stringify(frontmatter)\n\t\tconst fileContent = 'fileContent' as Part\n\n\t\tvi.useFakeTimers()\n\n\t\tmocks.generateContent.mockResolvedValueOnce({\n\t\t\ttext: responseText,\n\t\t} as GenerateContentResponse)\n\t\tmocks.uploadFile.mockResolvedValue({ name, uri, mimeType })\n\t\tmocks.getFile.mockResolvedValueOnce({ state: 'PROCESSING' as FileState })\n\t\tmocks.getFile.mockResolvedValueOnce({ uri, mimeType, state: 'ACTIVE' as FileState })\n\t\tmocks.fileTypeFromFile.mockResolvedValueOnce({ mime: mimeType, ext: 'pdf' })\n\t\tmocks.createPartFromUri.mockReturnValue(fileContent)\n\n\t\tvi.runAllTimersAsync()\n\n\t\tconst generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt, [file])\n\n\t\texpect(mocks.uploadFile).toHaveBeenCalledWith({ file, config: { mimeType } })\n\t\texpect(mocks.getFile).toHaveBeenCalledWith({ name })\n\t\texpect(mocks.createPartFromUri).toHaveBeenCalledTimes(1)\n\t\texpect(mocks.generateContent).toHaveBeenCalledTimes(1)\n\t\texpect(mocks.generateContent).toHaveBeenCalledWith({\n\t\t\tcontents: expect.arrayContaining([prompt, fileContent]),\n\t\t\tconfig: expect.any(Object),\n\t\t\tmodel: expect.any(String),\n\t\t})\n\t\texpect(generatedFrontmatter).toEqual(frontmatter)\n\n\t\tvi.useRealTimers()\n\t})\n\n\ttest('generatePieceFrontmatter with a text file', async () => {\n\t\tconst apiKey = 'apiKey'\n\t\tconst schema = makeSchema('books')\n\t\tconst prompt = 'prompt'\n\t\tconst file = '/path/to/file.html'\n\t\tconst frontmatter = { field: 'value' }\n\t\tconst responseText = JSON.stringify(frontmatter)\n\t\tconst fileContent = 'fileContent'\n\n\t\tmocks.generateContent.mockResolvedValueOnce({\n\t\t\ttext: responseText,\n\t\t} as GenerateContentResponse)\n\t\tmocks.fileTypeFromFile.mockResolvedValueOnce(undefined)\n\t\tmocks.readFile.mockResolvedValueOnce(fileContent)\n\n\t\tconst generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt, [file])\n\n\t\texpect(mocks.generateContent).toHaveBeenCalledTimes(1)\n\t\texpect(mocks.generateContent).toHaveBeenCalledWith({\n\t\t\tcontents: expect.arrayContaining([prompt, expect.stringContaining(fileContent)]),\n\t\t\tconfig: expect.any(Object),\n\t\t\tmodel: expect.any(String),\n\t\t})\n\t\texpect(generatedFrontmatter).toEqual(frontmatter)\n\n\t\tvi.useRealTimers()\n\t})\n\n\ttest('generatePieceFrontmatter with a text Buffer', async () => {\n\t\tconst apiKey = 'apiKey'\n\t\tconst schema = makeSchema('books')\n\t\tconst prompt = 'prompt'\n\t\tconst frontmatter = { field: 'value' }\n\t\tconst responseText = JSON.stringify(frontmatter)\n\t\tconst buffer = Buffer.from('buffer data')\n\n\t\tmocks.generateContent.mockResolvedValueOnce({\n\t\t\ttext: responseText,\n\t\t} as GenerateContentResponse)\n\t\tmocks.fileTypeFromBuffer.mockResolvedValueOnce(undefined)\n\n\t\tconst generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt, [buffer])\n\n\t\texpect(mocks.generateContent).toHaveBeenCalledTimes(1)\n\t\texpect(mocks.generateContent).toHaveBeenCalledWith({\n\t\t\tcontents: expect.arrayContaining([prompt, expect.stringContaining(buffer.toString())]),\n\t\t\tconfig: expect.any(Object),\n\t\t\tmodel: expect.any(String),\n\t\t})\n\n\t\texpect(generatedFrontmatter).toEqual(frontmatter)\n\t})\n\n\ttest('generatePieceFrontmatter with a binary Buffer', async () => {\n\t\tconst apiKey = 'apiKey'\n\t\tconst schema = makeSchema('books')\n\t\tconst prompt = 'prompt'\n\t\tconst name = 'file.pdf'\n\t\tconst uri = 'gs://another/path/to/file.pdf'\n\t\tconst mimeType = 'application/pdf'\n\t\tconst frontmatter = { field: 'value' }\n\t\tconst responseText = JSON.stringify(frontmatter)\n\t\tconst buffer = Buffer.from('buffer data')\n\t\tconst blob = new Blob([buffer])\n\t\tconst fileContent = 'fileContent' as Part\n\n\t\tmocks.generateContent.mockResolvedValueOnce({\n\t\t\ttext: responseText,\n\t\t} as GenerateContentResponse)\n\t\tmocks.uploadFile.mockResolvedValue({ name, uri, mimeType })\n\t\tmocks.getFile.mockResolvedValue({ uri, mimeType, state: 'ACTIVE' as FileState })\n\t\tmocks.fileTypeFromBuffer.mockResolvedValueOnce({ mime: mimeType, ext: 'pdf' })\n\t\tmocks.createPartFromUri.mockReturnValue(fileContent)\n\n\t\tconst generatedFrontmatter = await pieceFrontMatterFromPrompt(apiKey, schema, prompt, [buffer])\n\n\t\texpect(mocks.uploadFile).toHaveBeenCalledWith({ file: blob, config: { mimeType } })\n\t\texpect(mocks.getFile).toHaveBeenCalledWith({ name })\n\t\texpect(mocks.generateContent).toHaveBeenCalledTimes(1)\n\t\texpect(mocks.generateContent).toHaveBeenCalledWith({\n\t\t\tcontents: expect.arrayContaining([prompt, fileContent]),\n\t\t\tconfig: expect.any(Object),\n\t\t\tmodel: expect.any(String),\n\t\t})\n\n\t\texpect(generatedFrontmatter).toEqual(frontmatter)\n\t})\n\n\ttest('generatePieceFrontmatter binary file fails to process upload', async () => {\n\t\tconst apiKey = 'apiKey'\n\t\tconst schema = makeSchema('books')\n\t\tconst prompt = 'prompt'\n\t\tconst file = '/path/to/file.pdf'\n\t\tconst name = 'file.pdf'\n\t\tconst mimeType = 'application/pdf'\n\t\tconst frontmatter = { field: 'value' }\n\t\tconst responseText = JSON.stringify(frontmatter)\n\n\t\tmocks.generateContent.mockResolvedValueOnce({\n\t\t\ttext: responseText,\n\t\t} as GenerateContentResponse)\n\t\tmocks.uploadFile.mockResolvedValue({ name, state: 'FAILED' as FileState })\n\t\tmocks.getFile.mockResolvedValue({})\n\t\tmocks.fileTypeFromFile.mockResolvedValueOnce({ mime: mimeType, ext: 'pdf' })\n\n\t\tconst generating = pieceFrontMatterFromPrompt(apiKey, schema, prompt, [file])\n\n\t\texpect(generating).rejects.toThrowError()\n\t})\n\n\ttest('generatePieceFrontmatter file fails to extract', async () => {\n\t\tconst apiKey = 'apiKey'\n\t\tconst schema = makeSchema('books')\n\t\tconst prompt = 'prompt'\n\t\tconst file = '/path/to/file.pdf'\n\t\tconst name = 'file.pdf'\n\t\tconst mimeType = 'application/pdf'\n\t\tconst frontmatter = { field: 'value' }\n\t\tconst responseText = JSON.stringify(frontmatter)\n\n\t\tmocks.generateContent.mockResolvedValueOnce({\n\t\t\ttext: responseText,\n\t\t} as GenerateContentResponse)\n\t\tmocks.uploadFile.mockResolvedValue({ name, uri: undefined })\n\t\tmocks.getFile.mockResolvedValue({})\n\t\tmocks.fileTypeFromFile.mockResolvedValueOnce({ mime: mimeType, ext: 'pdf' })\n\n\t\tconst generating = pieceFrontMatterFromPrompt(apiKey, schema, prompt, [file])\n\n\t\texpect(generating).rejects.toThrowError()\n\t})\n})\n"]}
@@ -1 +0,0 @@
1
- export {};