@dbs-portal/tool-mock
Version:
API mocking toolkit using MSW for DBS Portal development workflows
286 lines • 8.35 kB
JavaScript
/**
* React Query integration for mock environments
*/
import { isMswSetup } from '../core/setup';
/**
* Create mock-aware query client configuration
*/
export function createMockQueryClientConfig(config = {}) {
const isMocking = isMswSetup();
const baseConfig = {
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000, // 5 minutes
cacheTime: 10 * 60 * 1000, // 10 minutes
retry: 3,
refetchOnWindowFocus: false,
refetchOnMount: true,
refetchOnReconnect: true,
...config.defaultOptions?.queries,
},
mutations: {
retry: 1,
...config.defaultOptions?.mutations,
},
},
};
// Adjust configuration for mock environment
if (isMocking && config.mockOptions) {
if (config.mockOptions.disableRetries) {
baseConfig.defaultOptions.queries.retry = false;
baseConfig.defaultOptions.mutations.retry = false;
}
if (config.mockOptions.fastStaleTime) {
baseConfig.defaultOptions.queries.staleTime = 1000; // 1 second
}
if (config.mockOptions.disableBackgroundRefetch) {
baseConfig.defaultOptions.queries.refetchOnWindowFocus = false;
baseConfig.defaultOptions.queries.refetchOnReconnect = false;
}
}
return baseConfig;
}
/**
* Mock query key factory
*/
export class MockQueryKeyFactory {
config;
constructor(config = {}) {
this.config = config;
}
/**
* Create query key for endpoint
*/
createKey(endpoint, params) {
if (this.config.queryKeyFactory) {
return this.config.queryKeyFactory(endpoint, params);
}
// Default implementation
const baseKey = [endpoint];
if (params) {
if (typeof params === 'object' && params !== null) {
// Sort object keys for consistent cache keys
const sortedParams = Object.keys(params)
.sort()
.reduce((result, key) => {
result[key] = params[key];
return result;
}, {});
baseKey.push(sortedParams);
}
else {
baseKey.push(params);
}
}
return baseKey;
}
/**
* Create list query key
*/
createListKey(endpoint, filters, pagination) {
const key = [endpoint, 'list'];
if (filters) {
key.push(JSON.stringify({ filters }));
}
if (pagination) {
key.push(JSON.stringify({ pagination }));
}
return key;
}
/**
* Create detail query key
*/
createDetailKey(endpoint, id) {
return [endpoint, 'detail', id];
}
/**
* Create mutation key
*/
createMutationKey(endpoint, operation) {
return [endpoint, 'mutation', operation];
}
}
/**
* Mock query utilities
*/
export const mockQueryUtils = {
/**
* Create mock query function
*/
createMockQuery: (queryKey, mockData, options = {}) => {
return {
queryKey,
queryFn: async () => {
if (options.delay) {
await new Promise(resolve => setTimeout(resolve, options.delay));
}
if (options.error) {
throw options.error;
}
return mockData;
},
};
},
/**
* Create mock infinite query
*/
createMockInfiniteQuery: (queryKey, mockDataPages, options = {}) => {
return {
queryKey,
queryFn: async ({ pageParam = 0 }) => {
if (options.delay) {
await new Promise(resolve => setTimeout(resolve, options.delay));
}
if (options.error) {
throw options.error;
}
const data = mockDataPages[pageParam];
if (!data) {
throw new Error(`No data found for page ${pageParam}`);
}
const nextCursor = pageParam + 1 < mockDataPages.length ? pageParam + 1 : undefined;
return {
data,
...(nextCursor !== undefined && { nextCursor })
};
},
getNextPageParam: (lastPage) => lastPage.nextCursor,
};
},
/**
* Create mock mutation
*/
createMockMutation: (mutationFn, options = {}) => {
return {
mutationFn: async (variables) => {
if (options.delay) {
await new Promise(resolve => setTimeout(resolve, options.delay));
}
if (options.error) {
throw options.error;
}
return mutationFn(variables);
},
};
},
};
/**
* Mock data invalidation utilities
*/
export class MockQueryInvalidation {
queryClient;
constructor(queryClient) {
this.queryClient = queryClient;
}
/**
* Invalidate queries by pattern
*/
invalidateByPattern(pattern) {
this.queryClient.invalidateQueries({
queryKey: pattern,
});
}
/**
* Invalidate all queries for an endpoint
*/
invalidateEndpoint(endpoint) {
this.queryClient.invalidateQueries({
queryKey: [endpoint],
});
}
/**
* Invalidate list queries
*/
invalidateList(endpoint) {
this.queryClient.invalidateQueries({
queryKey: [endpoint, 'list'],
});
}
/**
* Invalidate detail queries
*/
invalidateDetail(endpoint, id) {
const queryKey = id ? [endpoint, 'detail', id] : [endpoint, 'detail'];
this.queryClient.invalidateQueries({
queryKey,
});
}
/**
* Update query data directly
*/
updateQueryData(queryKey, updater) {
this.queryClient.setQueryData(queryKey, updater);
}
/**
* Set query data directly
*/
setQueryData(queryKey, data) {
this.queryClient.setQueryData(queryKey, data);
}
}
/**
* Create mock query hooks
*/
export function createMockQueryHooks(_queryKeyFactory) {
return {
/**
* Create mock useQuery hook
*/
useMockQuery: (_endpoint, _params, mockData, options) => {
// const queryKey = queryKeyFactory.createKey(endpoint, params) // Unused for now
return {
data: mockData,
isLoading: false,
isError: false,
error: null,
refetch: () => Promise.resolve({ data: mockData }),
...options,
};
},
/**
* Create mock useMutation hook
*/
useMockMutation: (_endpoint, mockResponse, options) => {
return {
mutate: (_variables) => {
return Promise.resolve(mockResponse);
},
mutateAsync: (_variables) => {
return Promise.resolve(mockResponse);
},
isLoading: false,
isError: false,
error: null,
data: undefined,
reset: () => { },
...options,
};
},
};
}
/**
* Integration with existing query patterns
*/
export function integrateMockQueries(queryClient, config = {}) {
const queryKeyFactory = new MockQueryKeyFactory(config);
const invalidation = new MockQueryInvalidation(queryClient);
const hooks = createMockQueryHooks(queryKeyFactory);
return {
queryKeyFactory,
invalidation,
hooks,
};
}
/**
* Mock query devtools integration
*/
export function setupMockQueryDevtools(_queryClient) {
if (typeof window !== 'undefined' && isMswSetup()) {
// Add mock indicator to React Query devtools
const originalDevtools = window.__REACT_QUERY_DEVTOOLS__;
if (originalDevtools) {
console.log('React Query running with MSW mock data');
}
}
}
//# sourceMappingURL=query.js.map