use-vibes 0.1.0 → 0.2.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,15 +0,0 @@
1
- import { Page } from '@playwright/test';
2
- /**
3
- * Helper function to inject and test the useVibes module in a browser context
4
- * This avoids the TypeScript errors from directly importing browser modules in Node.js
5
- */
6
- interface UseVibesConfig {
7
- prompt: string;
8
- [key: string]: unknown;
9
- }
10
- export declare function applyUseVibes(page: Page, selector: string, config: UseVibesConfig): Promise<void>;
11
- /**
12
- * Helper function to apply custom effects in a browser context
13
- */
14
- export declare function applyCustomEffect(page: Page, selector: string, effectFn: string): Promise<void>;
15
- export {};
@@ -1,32 +0,0 @@
1
- export async function applyUseVibes(page, selector, config) {
2
- await page.evaluate(({ selector, config }) => {
3
- return new Promise((resolve, reject) => {
4
- // Dynamically import the module within the browser context
5
- import('../../src/index.js')
6
- .then(({ useVibes }) => {
7
- const element = document.querySelector(selector);
8
- if (!element) {
9
- reject(new Error(`Element not found: ${selector}`));
10
- return;
11
- }
12
- useVibes(element, config)
13
- .then(() => resolve())
14
- .catch((err) => reject(err));
15
- })
16
- .catch((err) => reject(err));
17
- });
18
- }, { selector, config });
19
- }
20
- /**
21
- * Helper function to apply custom effects in a browser context
22
- */
23
- export async function applyCustomEffect(page, selector, effectFn) {
24
- await page.evaluate(({ selector, effectFn }) => {
25
- const element = document.querySelector(selector);
26
- if (!element)
27
- return;
28
- // Execute the string function in the browser context
29
- const fn = new Function('element', effectFn);
30
- fn(element);
31
- }, { selector, effectFn });
32
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,242 +0,0 @@
1
- // Mock implementation for the browser tests
2
- // This script will be injected into the test page before any tests run
3
- (function setupMocks() {
4
- // Module interception - CRITICAL: This must run before any other scripts
5
- // Create a module-level interception that redirects 'call-ai' imports to our mock
6
- // Debug indicator that helps us verify our mock is working
7
- window.__MOCK_STATUS__ = {
8
- initialized: true,
9
- moduleIntercepted: false,
10
- callCount: 0,
11
- lastPrompt: null,
12
- lastOptions: null,
13
- lastResponse: null,
14
- errors: [],
15
- };
16
- // Log that we're starting the mock setup
17
- /* eslint-disable-next-line no-console */
18
- console.log('🔄 MOCK SETUP: Initializing module interception for call-ai');
19
- try {
20
- // Define our mock implementation that will replace the real callAI
21
- const mockCallAI = function (userPrompt, options = {}) {
22
- // Track usage
23
- window.__MOCK_STATUS__.callCount++;
24
- window.__MOCK_STATUS__.lastPrompt = userPrompt;
25
- window.__MOCK_STATUS__.lastOptions = options;
26
- /* eslint-disable-next-line no-console */
27
- console.log(`🔍 MOCK CALL #${window.__MOCK_STATUS__.callCount}: callAI invoked with:`, typeof userPrompt === 'string'
28
- ? userPrompt.substring(0, 100) + '...'
29
- : '[non-string-prompt]');
30
- // Check if this is an error test case
31
- if (typeof userPrompt === 'string' &&
32
- (userPrompt.includes('error') || userPrompt.includes('fail'))) {
33
- /* eslint-disable-next-line no-console */
34
- console.log('🚨 MOCK: Simulating error response');
35
- return Promise.reject(new Error('Simulated error from mock callAI'));
36
- }
37
- // Extract the actual request from the longer prompt
38
- let extractedPrompt = 'Default prompt';
39
- if (typeof userPrompt === 'string') {
40
- const promptMatch = userPrompt.match(/Transform the HTML content based on this request:\s*([^\n]+)/);
41
- if (promptMatch && promptMatch[1]) {
42
- extractedPrompt = promptMatch[1].trim();
43
- }
44
- else if (userPrompt.includes('Alternative configuration test')) {
45
- extractedPrompt = 'Alternative configuration test';
46
- }
47
- }
48
- // Create response HTML based on the prompt content
49
- let htmlContent;
50
- let explanationText;
51
- if (extractedPrompt.includes('Alternative configuration')) {
52
- htmlContent = `<div style="background-color: #fff8e1; padding: 10px; border: 2px solid #ffc107; border-radius: 5px;">
53
- <strong>🎭 Vibes received prompt:</strong> "Alternative configuration test"
54
- <br><small>(Alternative config mock response)</small>
55
- </div>`;
56
- explanationText = 'Mock explanation for alternative configuration';
57
- }
58
- else {
59
- htmlContent = `<div style="background-color: #eefbff; padding: 10px; border: 2px solid #0099cc; border-radius: 5px;">
60
- <strong>🎭 Vibes received prompt:</strong> "${extractedPrompt}"
61
- <br><small>(This is a mock response from browser test)</small>
62
- </div>`;
63
- explanationText = 'This is a mock explanation from the browser test';
64
- }
65
- // Create the structured response object that matches the schema in useVibes
66
- const responseObj = {
67
- html: htmlContent,
68
- explanation: explanationText,
69
- };
70
- // Store for debugging
71
- window.__MOCK_STATUS__.lastResponse = responseObj;
72
- /* eslint-disable-next-line no-console */
73
- console.log('✅ MOCK: Created JSON response:', JSON.stringify(responseObj).substring(0, 100) + '...');
74
- // Return a properly structured response that matches what useVibes expects
75
- return Promise.resolve(JSON.stringify(responseObj));
76
- };
77
- // Create a mock module object that matches the structure of the real call-ai module
78
- const mockModule = {
79
- callAI: mockCallAI,
80
- __isMock: true,
81
- };
82
- // Attempt multiple interception strategies for maximum browser compatibility
83
- // Strategy 1: Intercept dynamic imports
84
- // This works with newer module bundlers like Vite, Webpack, etc.
85
- const originalImport = window.import;
86
- window.import = function (specifier) {
87
- if (specifier === 'call-ai') {
88
- /* eslint-disable-next-line no-console */
89
- console.log('🎯 MOCK: Import intercepted for call-ai module');
90
- window.__MOCK_STATUS__.moduleIntercepted = true;
91
- return Promise.resolve(mockModule);
92
- }
93
- return originalImport.apply(this, arguments);
94
- };
95
- // Strategy 2: Define the module globally for ESM imports to find
96
- // Helps with static imports which can't be intercepted directly
97
- window.mockCallAI = mockCallAI;
98
- // Also set window.callAI for direct access tests
99
- window.callAI = mockCallAI;
100
- /* eslint-disable-next-line no-console */
101
- console.log('✅ MOCK SETUP: Module interception complete - callAI has been mocked');
102
- }
103
- catch (error) {
104
- console.error('❌ MOCK SETUP ERROR:', error);
105
- window.__MOCK_STATUS__.errors.push(error.message);
106
- }
107
- // Flag to indicate mocks are initialized
108
- window.mockInitialized = true;
109
- // eslint-disable-next-line no-console
110
- console.log('-----------------------------------------------------------');
111
- // eslint-disable-next-line no-console
112
- console.log('🔧 MOCK SETUP: Setting up call-ai mocks for browser tests...');
113
- // eslint-disable-next-line no-console
114
- console.log('-----------------------------------------------------------');
115
- // Create a global debug flag to track what's happening with our mocks
116
- window.MOCK_DEBUG = {
117
- mockCallsCount: 0,
118
- lastPrompt: null,
119
- lastResponse: null,
120
- };
121
- // Mock the callAI function directly to ensure tests work correctly
122
- // This is the most reliable way to mock the call-ai module
123
- window.callAI = function mockCallAI(userPrompt, options = {}) {
124
- window.MOCK_DEBUG.mockCallsCount++;
125
- // eslint-disable-next-line no-console
126
- console.log('🔄 MOCK INTERCEPTED: callAI invoked - call #', window.MOCK_DEBUG.mockCallsCount);
127
- // eslint-disable-next-line no-console
128
- console.log('📝 MOCK PROMPT:', typeof userPrompt === 'string' ? userPrompt.substring(0, 100) + '...' : 'Non-string prompt');
129
- // eslint-disable-next-line no-console
130
- console.log('⚙️ MOCK OPTIONS:', JSON.stringify(options));
131
- // Store the prompt for debugging
132
- window.MOCK_DEBUG.lastPrompt = userPrompt;
133
- window.MOCK_DEBUG.lastOptions = options;
134
- // Extract the actual request from the longer prompt - more robust regex handling
135
- let extractedPrompt = 'Default prompt';
136
- if (typeof userPrompt === 'string') {
137
- const promptMatch = userPrompt.match(/Transform the HTML content based on this request:\s*([^\n]+)/);
138
- if (promptMatch && promptMatch[1]) {
139
- extractedPrompt = promptMatch[1].trim();
140
- }
141
- else if (userPrompt.includes('Alternative configuration test')) {
142
- extractedPrompt = 'Alternative configuration test';
143
- }
144
- else if (userPrompt.includes('error') || userPrompt.includes('fail')) {
145
- extractedPrompt = 'Error simulation test';
146
- }
147
- else {
148
- // Just use a substring as a fallback - don't let tests fail because of regex
149
- extractedPrompt = userPrompt.length > 50 ? userPrompt.substring(0, 50) + '...' : userPrompt;
150
- }
151
- }
152
- // eslint-disable-next-line no-console
153
- console.log('🔍 EXTRACTED PROMPT:', extractedPrompt);
154
- // Check if this is an error test case
155
- if (extractedPrompt.includes('error') || extractedPrompt.includes('fail')) {
156
- // eslint-disable-next-line no-console
157
- console.log('🚨 SIMULATING ERROR RESPONSE');
158
- return Promise.reject(new Error('Simulated error from mock callAI'));
159
- }
160
- // Create response based on the prompt content
161
- let htmlContent;
162
- let explanationText;
163
- if (extractedPrompt.includes('Alternative configuration')) {
164
- // Custom response for alternative config test
165
- htmlContent = `<div style="background-color: #fff8e1; padding: 10px; border: 2px solid #ffc107; border-radius: 5px;">
166
- <strong>🎭 Vibes received prompt:</strong> "Alternative configuration test"
167
- <br><small>(Alternative config mock response)</small>
168
- </div>`;
169
- explanationText = 'Mock explanation for alternative configuration';
170
- }
171
- else {
172
- // Default response
173
- htmlContent = `<div style="background-color: #eefbff; padding: 10px; border: 2px solid #0099cc; border-radius: 5px;">
174
- <strong>🎭 Vibes received prompt:</strong> "${extractedPrompt}"
175
- <br><small>(This is a mock response from browser test)</small>
176
- </div>`;
177
- explanationText = 'This is a mock explanation from the browser test';
178
- }
179
- // Create the response object in the exact format that useVibes expects
180
- const responseObj = {
181
- html: htmlContent,
182
- explanation: explanationText,
183
- };
184
- // Store the response for debugging
185
- window.MOCK_DEBUG.lastResponse = responseObj;
186
- // eslint-disable-next-line no-console
187
- console.log('✅ MOCK RESPONSE CREATED:', JSON.stringify(responseObj).substring(0, 100) + '...');
188
- // useVibes expects a Promise that resolves to a string (JSON)
189
- return Promise.resolve(JSON.stringify(responseObj));
190
- };
191
- // As a fallback, also mock fetch for any direct API calls
192
- // Store the original fetch
193
- window._originalFetch = window.fetch;
194
- // Mock the fetch API for call-ai
195
- window.fetch = async function mockedFetch(url, options) {
196
- // Check if this is a call to the AI API
197
- if (url && (url.includes('api.call-ai.com') || url.includes('api/v1/chat/completions'))) {
198
- // eslint-disable-next-line no-console
199
- console.log('Intercepted fetch call to:', url);
200
- // Parse the request body to get the prompt
201
- const requestBody = JSON.parse(options.body);
202
- let promptText = '';
203
- // Extract prompt from messages
204
- if (requestBody.messages && requestBody.messages.length > 0) {
205
- const lastMessage = requestBody.messages[requestBody.messages.length - 1];
206
- promptText = lastMessage.content || '';
207
- }
208
- // Create a properly formatted mock response
209
- const mockResponse = {
210
- choices: [
211
- {
212
- message: {
213
- role: 'assistant',
214
- content: JSON.stringify({
215
- html: `<div>🎭 Vibes received prompt: "${promptText}"</div>`,
216
- explanation: 'This is a mock explanation from the browser test',
217
- }),
218
- },
219
- index: 0,
220
- },
221
- ],
222
- id: 'mock-response-id',
223
- model: 'gpt-3.5-turbo',
224
- object: 'chat.completion',
225
- };
226
- // Return a Response object with the mock data
227
- return new Response(JSON.stringify(mockResponse), {
228
- status: 200,
229
- headers: { 'Content-Type': 'application/json' },
230
- });
231
- }
232
- // For any other fetch calls, use the original implementation
233
- return window._originalFetch(url, options);
234
- };
235
- // eslint-disable-next-line no-console
236
- console.log('-----------------------------------------------------------');
237
- // eslint-disable-next-line no-console
238
- console.log('✅ MOCK SETUP COMPLETE: All mocks for callAI and fetch API ready!');
239
- // eslint-disable-next-line no-console
240
- console.log('-----------------------------------------------------------');
241
- })();
242
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1,60 +0,0 @@
1
- import { describe, it, expect, beforeEach, vi } from 'vitest';
2
- import { useVibes } from '../src/index.js';
3
- // Mock the call-ai module for testing
4
- vi.mock('call-ai', () => {
5
- return {
6
- callAI: vi.fn().mockImplementation((prompt, options) => {
7
- if (options?.stream === false) {
8
- // Extract prompt content for the mock response
9
- let promptText = 'Test prompt';
10
- if (typeof prompt === 'string' && prompt.includes('request:')) {
11
- promptText = prompt.split('request:')[1].split('\n')[0].trim();
12
- }
13
- // Create a properly formatted mock response that matches the schema
14
- const mockResponse = JSON.stringify({
15
- html: `<div>🎭 Vibes received prompt: "${promptText}"</div>`,
16
- explanation: 'This is a mock explanation from the test',
17
- });
18
- return Promise.resolve(mockResponse);
19
- }
20
- // For any other case
21
- return 'Direct response';
22
- }),
23
- };
24
- });
25
- // Setup test DOM elements before each test
26
- beforeEach(() => {
27
- // Reset the body content
28
- document.body.innerHTML = '';
29
- // Create test elements
30
- const target = document.createElement('div');
31
- target.id = 'target';
32
- document.body.appendChild(target);
33
- const targetAlt = document.createElement('div');
34
- targetAlt.id = 'target-alt';
35
- document.body.appendChild(targetAlt);
36
- });
37
- describe('useVibes function', () => {
38
- it('should accept a string selector and apply changes to the target element', async () => {
39
- const result = await useVibes('#target', { prompt: 'Test prompt' });
40
- expect(result.container).toBeDefined();
41
- expect(result.container.innerHTML).toContain('Vibes received prompt: "Test prompt"');
42
- });
43
- it('should accept an HTMLElement directly', async () => {
44
- const targetElement = document.getElementById('target');
45
- if (!targetElement)
46
- throw new Error('Test setup failed: target element not found');
47
- const result = await useVibes(targetElement, { prompt: 'Direct element test' });
48
- expect(result.container).toBe(targetElement);
49
- expect(result.container.innerHTML).toContain('Vibes received prompt: "Direct element test"');
50
- });
51
- it('should reject with an error when target element not found', async () => {
52
- await expect(useVibes('#non-existent', { prompt: 'Test' })).rejects.toThrow('Target element not found: #non-existent');
53
- });
54
- it('should return an object with the expected interface properties', async () => {
55
- const result = await useVibes('#target', { prompt: 'Interface test' });
56
- expect(result).toHaveProperty('container');
57
- expect(result).toHaveProperty('database');
58
- expect(result.database).toBeUndefined(); // Currently undefined in the implementation
59
- });
60
- });