@positronic/core 0.0.3 → 0.0.4

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,248 +0,0 @@
1
- import { createResources, type Manifest } from '../src/resources/resources.js';
2
- import { ResourceLoader } from '../src/resources/resource-loader.js';
3
-
4
- // Mock loader for testing
5
- class MockLoader implements ResourceLoader {
6
- private mockData: Record<string, string | Buffer> = {
7
- 'example.md': 'Example content',
8
- 'my file with spaces.txt': 'Content with spaces in filename',
9
- 'data/2024-report.pdf': Buffer.from('Mock PDF content'),
10
- 'docs/readme.md': 'Documentation content',
11
- 'special-chars!@#.txt': 'Special characters content',
12
- };
13
-
14
- addMockData(path: string, content: string | Buffer): void {
15
- this.mockData[path] = content;
16
- }
17
-
18
- async load(key: string, type: 'text'): Promise<string>;
19
- async load(key: string, type: 'binary'): Promise<Buffer>;
20
- async load(key: string, type: 'text' | 'binary'): Promise<string | Buffer> {
21
- const data = this.mockData[key];
22
- if (!data) {
23
- throw new Error(`Resource not found: ${key}`);
24
- }
25
-
26
- if (type === 'text' && Buffer.isBuffer(data)) {
27
- return data.toString();
28
- }
29
- if (type === 'binary' && typeof data === 'string') {
30
- return Buffer.from(data);
31
- }
32
-
33
- return data;
34
- }
35
- }
36
-
37
- describe('Resources API', () => {
38
- let resources: any;
39
-
40
- beforeEach(() => {
41
- const manifest: Manifest = {
42
- 'example.md': {
43
- type: 'text',
44
- path: 'example.md',
45
- key: 'example.md',
46
- },
47
- 'my file with spaces.txt': {
48
- type: 'text',
49
- path: 'my file with spaces.txt',
50
- key: 'my file with spaces.txt',
51
- },
52
- data: {
53
- '2024-report.pdf': {
54
- type: 'binary',
55
- path: 'data/2024-report.pdf',
56
- key: 'data/2024-report.pdf',
57
- },
58
- },
59
- docs: {
60
- 'readme.md': {
61
- type: 'text',
62
- path: 'docs/readme.md',
63
- key: 'docs/readme.md',
64
- },
65
- },
66
- 'special-chars!@#.txt': {
67
- type: 'text',
68
- path: 'special-chars!@#.txt',
69
- key: 'special-chars!@#.txt',
70
- },
71
- };
72
-
73
- const loader = new MockLoader();
74
- resources = createResources(loader, manifest);
75
- });
76
-
77
- describe('Proxy API (for JS-identifier compatible names)', () => {
78
- it('should load simple resource via proxy', async () => {
79
- const content = await resources.example.loadText();
80
- expect(content).toBe('Example content');
81
- });
82
-
83
- it('should load nested resource via proxy', async () => {
84
- const content = await resources.docs.readme.loadText();
85
- expect(content).toBe('Documentation content');
86
- });
87
-
88
- it('should load binary resource via proxy', async () => {
89
- const buffer = await resources.data['2024-report.pdf'].loadBinary();
90
- expect(buffer.toString()).toBe('Mock PDF content');
91
- });
92
- });
93
-
94
- describe('Method API (for any filename)', () => {
95
- it('should load resource with spaces in name', async () => {
96
- const content = await resources.loadText('my file with spaces.txt');
97
- expect(content).toBe('Content with spaces in filename');
98
- });
99
-
100
- it('should load nested resource by path', async () => {
101
- const content = await resources.loadText('docs/readme.md');
102
- expect(content).toBe('Documentation content');
103
- });
104
-
105
- it('should load binary resource by path', async () => {
106
- const buffer = await resources.loadBinary('data/2024-report.pdf');
107
- expect(buffer.toString()).toBe('Mock PDF content');
108
- });
109
-
110
- it('should load resource with special characters', async () => {
111
- const content = await resources.loadText('special-chars!@#.txt');
112
- expect(content).toBe('Special characters content');
113
- });
114
-
115
- it('should throw error for non-existent resource', async () => {
116
- await expect(resources.loadText('non-existent.txt')).rejects.toThrow(
117
- 'Resource not found: non-existent.txt'
118
- );
119
- });
120
-
121
- it('should throw error when using wrong type method', async () => {
122
- await expect(resources.loadText('data/2024-report.pdf')).rejects.toThrow(
123
- 'Resource "data/2024-report.pdf" is of type "binary", but was accessed with loadText()'
124
- );
125
-
126
- await expect(resources.loadBinary('example.md')).rejects.toThrow(
127
- 'Resource "example.md" is of type "text", but was accessed with loadBinary()'
128
- );
129
- });
130
- });
131
-
132
- describe('Mixed usage', () => {
133
- it('should support both APIs in the same brain', async () => {
134
- // Use proxy API for clean names
135
- const example = await resources.example.loadText();
136
-
137
- // Use method API for names with spaces
138
- const withSpaces = await resources.loadText('my file with spaces.txt');
139
-
140
- // Both should work
141
- expect(example).toBe('Example content');
142
- expect(withSpaces).toBe('Content with spaces in filename');
143
- });
144
- });
145
-
146
- describe('Ambiguous resource names', () => {
147
- let ambiguousResources: any;
148
-
149
- beforeEach(() => {
150
- const ambiguousManifest: Manifest = {
151
- 'example.md': {
152
- type: 'text',
153
- path: 'example.md',
154
- key: 'example.md',
155
- },
156
- 'example.txt': {
157
- type: 'text',
158
- path: 'example.txt',
159
- key: 'example.txt',
160
- },
161
- 'report.pdf': {
162
- type: 'binary',
163
- path: 'report.pdf',
164
- key: 'report.pdf',
165
- },
166
- 'report.docx': {
167
- type: 'binary',
168
- path: 'report.docx',
169
- key: 'report.docx',
170
- },
171
- nested: {
172
- 'config.json': {
173
- type: 'text',
174
- path: 'nested/config.json',
175
- key: 'nested/config.json',
176
- },
177
- 'config.yaml': {
178
- type: 'text',
179
- path: 'nested/config.yaml',
180
- key: 'nested/config.yaml',
181
- },
182
- },
183
- };
184
-
185
- const mockLoader = new MockLoader();
186
- // Add the ambiguous files to mock data
187
- mockLoader.addMockData('example.md', 'Example markdown content');
188
- mockLoader.addMockData('example.txt', 'Example text content');
189
- mockLoader.addMockData('report.pdf', Buffer.from('PDF content'));
190
- mockLoader.addMockData('report.docx', Buffer.from('DOCX content'));
191
- mockLoader.addMockData('nested/config.json', '{"config": "json"}');
192
- mockLoader.addMockData('nested/config.yaml', 'config: yaml');
193
-
194
- ambiguousResources = createResources(mockLoader, ambiguousManifest);
195
- });
196
-
197
- it('should throw error when accessing ambiguous resource via proxy', () => {
198
- expect(() => ambiguousResources.example).toThrow(
199
- "Ambiguous resource name 'example': found example.md, example.txt. " +
200
- "Please use resources.loadText('example.md') or resources.loadBinary('example.txt') instead."
201
- );
202
- });
203
-
204
- it('should throw error for ambiguous binary resources', () => {
205
- expect(() => ambiguousResources.report).toThrow(
206
- "Ambiguous resource name 'report': found report.pdf, report.docx"
207
- );
208
- });
209
-
210
- it('should throw error for ambiguous nested resources', () => {
211
- expect(() => ambiguousResources.nested.config).toThrow(
212
- "Ambiguous resource name 'config': found config.json, config.yaml"
213
- );
214
- });
215
-
216
- it('should allow direct access with full filename', async () => {
217
- const markdownContent = await ambiguousResources['example.md'].loadText();
218
- const textContent = await ambiguousResources['example.txt'].loadText();
219
-
220
- expect(markdownContent).toBe('Example markdown content');
221
- expect(textContent).toBe('Example text content');
222
- });
223
-
224
- it('should work with method API for ambiguous resources', async () => {
225
- const markdownContent = await ambiguousResources.loadText('example.md');
226
- const textContent = await ambiguousResources.loadText('example.txt');
227
-
228
- expect(markdownContent).toBe('Example markdown content');
229
- expect(textContent).toBe('Example text content');
230
- });
231
-
232
- it('should handle ambiguous paths in loadText/loadBinary methods', async () => {
233
- // Should work with full path
234
- const jsonContent = await ambiguousResources.loadText(
235
- 'nested/config.json'
236
- );
237
- expect(jsonContent).toBe('{"config": "json"}');
238
-
239
- // Should throw error for ambiguous path without extension
240
- await expect(
241
- ambiguousResources.loadText('nested/config')
242
- ).rejects.toThrow(
243
- "Ambiguous resource path 'nested/config': found config.json, config.yaml. " +
244
- 'Please specify the full filename with extension.'
245
- );
246
- });
247
- });
248
- });
package/tsconfig.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "compilerOptions": {
4
- "rootDir": "./src",
5
- "emitDeclarationOnly": true,
6
- "declarationDir": "./dist/types"
7
- },
8
- "include": ["src/**/*"],
9
- "exclude": ["dist", "node_modules", "**/*.test.ts"]
10
- }