@nocios/crudify-components 2.0.61 → 2.0.88

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 (85) hide show
  1. package/README.md +21 -0
  2. package/dist/api-jcCTCqPD.d.mts +61 -0
  3. package/dist/api-jcCTCqPD.d.ts +61 -0
  4. package/dist/chunk-4I767MRM.mjs +142 -0
  5. package/dist/chunk-5V5ILPP3.js +1 -0
  6. package/dist/chunk-BJEDX2HU.js +142 -0
  7. package/dist/chunk-GZOB4JDB.js +1 -0
  8. package/dist/chunk-ODKXUEH5.js +1 -0
  9. package/dist/chunk-U335FNUD.mjs +1 -0
  10. package/dist/chunk-YRU7AXYV.mjs +1 -0
  11. package/dist/chunk-Z75DRSTN.mjs +1 -0
  12. package/dist/{errorTranslation-CF-5JClP.d.ts → errorTranslation-BdqG-dXD.d.ts} +97 -26
  13. package/dist/{errorTranslation-BcX8AaK7.d.mts → errorTranslation-BxJmBGx0.d.mts} +97 -26
  14. package/dist/hooks.d.mts +3 -4
  15. package/dist/hooks.d.ts +3 -4
  16. package/dist/hooks.js +1 -1
  17. package/dist/hooks.mjs +1 -1
  18. package/dist/{index-D06kTP0C.d.mts → index-Cx9P3ZCG.d.mts} +225 -139
  19. package/dist/{index-DEDnmsdO.d.ts → index-rHtWMls-.d.ts} +225 -139
  20. package/dist/index.d.mts +508 -213
  21. package/dist/index.d.ts +508 -213
  22. package/dist/index.js +2 -2
  23. package/dist/index.mjs +2 -2
  24. package/dist/public-policies.d.mts +7 -0
  25. package/dist/public-policies.d.ts +7 -0
  26. package/dist/public-policies.js +1 -0
  27. package/dist/public-policies.mjs +1 -0
  28. package/dist/utils.d.mts +94 -26
  29. package/dist/utils.d.ts +94 -26
  30. package/dist/utils.js +1 -1
  31. package/dist/utils.mjs +1 -1
  32. package/package.json +44 -42
  33. package/.github/workflows/ci.yml +0 -70
  34. package/.husky/pre-commit +0 -26
  35. package/.husky/pre-push +0 -30
  36. package/.nvmrc +0 -1
  37. package/.prettierignore +0 -18
  38. package/.prettierrc +0 -9
  39. package/README_DEPTH.md +0 -1237
  40. package/coverage/base.css +0 -224
  41. package/coverage/block-navigation.js +0 -87
  42. package/coverage/coverage-final.json +0 -120
  43. package/coverage/favicon.png +0 -0
  44. package/coverage/index.html +0 -686
  45. package/coverage/lcov-report/base.css +0 -224
  46. package/coverage/lcov-report/block-navigation.js +0 -87
  47. package/coverage/lcov-report/favicon.png +0 -0
  48. package/coverage/lcov-report/index.html +0 -686
  49. package/coverage/lcov-report/prettify.css +0 -1
  50. package/coverage/lcov-report/prettify.js +0 -2
  51. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  52. package/coverage/lcov-report/sorter.js +0 -210
  53. package/coverage/lcov.info +0 -22388
  54. package/coverage/prettify.css +0 -1
  55. package/coverage/prettify.js +0 -2
  56. package/coverage/sort-arrow-sprite.png +0 -0
  57. package/coverage/sorter.js +0 -210
  58. package/dist/CrudiaMarkdownField-CkiBwG-U.d.ts +0 -343
  59. package/dist/CrudiaMarkdownField-D-DqiXMQ.d.mts +0 -343
  60. package/dist/GlobalNotificationProvider-CdwdNv_8.d.mts +0 -96
  61. package/dist/GlobalNotificationProvider-CdwdNv_8.d.ts +0 -96
  62. package/dist/chunk-2WAUZ6KI.js +0 -1
  63. package/dist/chunk-3IGZNZCT.mjs +0 -1
  64. package/dist/chunk-43L2PP77.mjs +0 -1
  65. package/dist/chunk-6VS5OT3A.mjs +0 -1
  66. package/dist/chunk-BWJTTMKS.js +0 -1
  67. package/dist/chunk-EMPPCCVU.js +0 -1
  68. package/dist/chunk-J43UPGBE.js +0 -1
  69. package/dist/chunk-K6ZRXOJ7.mjs +0 -1
  70. package/dist/chunk-RYQQZTEP.js +0 -1
  71. package/dist/chunk-VTMSOK4V.mjs +0 -1
  72. package/dist/components.d.mts +0 -24
  73. package/dist/components.d.ts +0 -24
  74. package/dist/components.js +0 -1
  75. package/dist/components.mjs +0 -1
  76. package/dist/tenantConfig-CYnS9TPV.d.mts +0 -318
  77. package/dist/tenantConfig-CYnS9TPV.d.ts +0 -318
  78. package/eslint.config.mjs +0 -140
  79. package/scripts/bump-version.cjs +0 -23
  80. package/sonar-project.properties +0 -23
  81. package/tests/helpers/testUtils.tsx +0 -89
  82. package/tests/hooks/useSession/testUtils.tsx +0 -212
  83. package/tests/setup.ts +0 -139
  84. package/tests/vitest.d.ts +0 -1
  85. package/vitest.config.ts +0 -39
package/eslint.config.mjs DELETED
@@ -1,140 +0,0 @@
1
- import tseslint from '@typescript-eslint/eslint-plugin';
2
- import tsparser from '@typescript-eslint/parser';
3
- import react from 'eslint-plugin-react';
4
- import reactHooks from 'eslint-plugin-react-hooks';
5
-
6
- export default [
7
- {
8
- ignores: ['dist/**', 'node_modules/**', 'coverage/**'],
9
- },
10
- // Configuracion para archivos TypeScript (.ts)
11
- {
12
- files: ['src/**/*.ts'],
13
- languageOptions: {
14
- parser: tsparser,
15
- parserOptions: {
16
- ecmaVersion: 'latest',
17
- sourceType: 'module',
18
- },
19
- },
20
- plugins: {
21
- '@typescript-eslint': tseslint,
22
- },
23
- rules: {
24
- ...tseslint.configs.recommended.rules,
25
- '@typescript-eslint/no-unused-vars': [
26
- 'error',
27
- { argsIgnorePattern: '^_', varsIgnorePattern: '^_', destructuredArrayIgnorePattern: '^_' },
28
- ],
29
- '@typescript-eslint/no-explicit-any': 'warn',
30
- '@typescript-eslint/explicit-function-return-type': 'off',
31
- '@typescript-eslint/no-non-null-assertion': 'warn',
32
- 'curly': ['error', 'all'],
33
- 'brace-style': ['error', '1tbs', { allowSingleLine: false }],
34
- 'no-console': 'warn',
35
- 'no-restricted-syntax': [
36
- 'error',
37
- {
38
- selector: 'ExportDefaultDeclaration',
39
- message: 'Prefer named exports instead of default exports',
40
- },
41
- ],
42
- },
43
- },
44
- // Configuracion para archivos React (.tsx)
45
- {
46
- files: ['src/**/*.tsx'],
47
- languageOptions: {
48
- parser: tsparser,
49
- parserOptions: {
50
- ecmaVersion: 'latest',
51
- sourceType: 'module',
52
- ecmaFeatures: {
53
- jsx: true,
54
- },
55
- },
56
- },
57
- plugins: {
58
- '@typescript-eslint': tseslint,
59
- react: react,
60
- 'react-hooks': reactHooks,
61
- },
62
- settings: {
63
- react: {
64
- version: 'detect',
65
- },
66
- },
67
- rules: {
68
- ...tseslint.configs.recommended.rules,
69
- ...react.configs.recommended.rules,
70
- ...reactHooks.configs.recommended.rules,
71
- '@typescript-eslint/no-unused-vars': [
72
- 'error',
73
- { argsIgnorePattern: '^_', varsIgnorePattern: '^_', destructuredArrayIgnorePattern: '^_' },
74
- ],
75
- '@typescript-eslint/no-explicit-any': 'warn',
76
- '@typescript-eslint/explicit-function-return-type': 'off',
77
- '@typescript-eslint/no-non-null-assertion': 'warn',
78
- 'curly': ['error', 'all'],
79
- 'brace-style': ['error', '1tbs', { allowSingleLine: false }],
80
- 'no-console': 'warn',
81
- // React 17+ no requiere importar React
82
- 'react/react-in-jsx-scope': 'off',
83
- // Props spreading es comun en componentes UI
84
- 'react/jsx-props-no-spreading': 'off',
85
- // Usamos TypeScript para validar props, no necesitamos prop-types
86
- 'react/prop-types': 'off',
87
- // Para componentes, permitir default exports (warn en lugar de error)
88
- 'no-restricted-syntax': [
89
- 'warn',
90
- {
91
- selector: 'ExportDefaultDeclaration',
92
- message: 'Consider using named exports instead of default exports',
93
- },
94
- ],
95
- },
96
- },
97
- // Configuracion mas permisiva para archivos de test
98
- {
99
- files: [
100
- 'src/**/*.test.ts',
101
- 'src/**/*.test.tsx',
102
- 'src/**/*.spec.ts',
103
- 'src/**/*.spec.tsx',
104
- 'src/__tests__/**/*.ts',
105
- 'src/__tests__/**/*.tsx',
106
- ],
107
- rules: {
108
- '@typescript-eslint/no-unused-vars': 'warn',
109
- '@typescript-eslint/no-explicit-any': 'off',
110
- '@typescript-eslint/no-unsafe-function-type': 'off',
111
- '@typescript-eslint/no-non-null-assertion': 'off',
112
- '@typescript-eslint/ban-ts-comment': 'off',
113
- 'no-console': 'off',
114
- },
115
- },
116
- // Configuracion para hooks .ts (agregar react-hooks y permitir default exports con warning)
117
- {
118
- files: ['src/**/hooks/**/*.ts', 'src/hooks/**/*.ts'],
119
- plugins: {
120
- 'react-hooks': reactHooks,
121
- },
122
- rules: {
123
- ...reactHooks.configs.recommended.rules,
124
- 'no-restricted-syntax': [
125
- 'warn',
126
- {
127
- selector: 'ExportDefaultDeclaration',
128
- message: 'Consider using named exports instead of default exports',
129
- },
130
- ],
131
- },
132
- },
133
- // Configuracion para archivos de declaracion (.d.ts) - permiten default exports para CSS modules
134
- {
135
- files: ['src/**/*.d.ts'],
136
- rules: {
137
- 'no-restricted-syntax': 'off',
138
- },
139
- },
140
- ];
@@ -1,23 +0,0 @@
1
- /**
2
- * Auto-increment patch version in package.json
3
- *
4
- * This script increments the patch version (e.g., 2.0.44 -> 2.0.45)
5
- * and writes it back to package.json
6
- */
7
- const fs = require('fs');
8
- const path = require('path');
9
-
10
- const packagePath = path.join(__dirname, '../package.json');
11
- const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
12
-
13
- // Parse current version
14
- const [major, minor, patch] = pkg.version.split('.').map(Number);
15
-
16
- // Increment patch version
17
- const newVersion = `${major}.${minor}.${patch + 1}`;
18
-
19
- // Update package.json
20
- pkg.version = newVersion;
21
- fs.writeFileSync(packagePath, JSON.stringify(pkg, null, 2) + '\n');
22
-
23
- console.log(`✓ Version bumped: ${major}.${minor}.${patch} → ${newVersion}`);
@@ -1,23 +0,0 @@
1
- # Identificacion del proyecto
2
- sonar.projectKey=nocios_crudify-components
3
- sonar.projectName=crudify-components
4
- sonar.projectVersion=2.0.44
5
-
6
- # Configuracion de fuentes
7
- sonar.sources=src
8
- sonar.tests=tests
9
- sonar.sourceEncoding=UTF-8
10
-
11
- # Reporte de cobertura
12
- sonar.typescript.lcov.reportPaths=coverage/lcov.info
13
- sonar.javascript.lcov.reportPaths=coverage/lcov.info
14
-
15
- # Exclusiones
16
- sonar.exclusions=**/node_modules/**,**/dist/**,**/*.test.ts,**/*.spec.ts,**/*.test.tsx,**/*.spec.tsx,**/example/**
17
- sonar.coverage.exclusions=**/index.ts,**/types.ts,**/types.d.ts,**/*.d.ts
18
-
19
- # Inclusiones de tests
20
- sonar.test.inclusions=tests/**/*.test.ts,tests/**/*.spec.ts,tests/**/*.test.tsx,tests/**/*.spec.tsx
21
-
22
- # Quality Gate
23
- sonar.qualitygate.wait=true
@@ -1,89 +0,0 @@
1
- /**
2
- * Test Utilities
3
- * Common utilities and helpers for testing
4
- */
5
-
6
- import { render, RenderOptions, RenderResult } from '@testing-library/react';
7
- import { ReactElement, ReactNode } from 'react';
8
-
9
- /**
10
- * Custom render function with providers
11
- */
12
- export function renderWithProviders(ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>): RenderResult {
13
- function Wrapper({ children }: { children: ReactNode }) {
14
- return <>{children}</>;
15
- }
16
-
17
- return render(ui, { wrapper: Wrapper, ...options });
18
- }
19
-
20
- /**
21
- * Wait for a condition to be true
22
- */
23
- export async function waitForCondition(condition: () => boolean, timeout = 5000): Promise<void> {
24
- const startTime = Date.now();
25
- while (!condition()) {
26
- if (Date.now() - startTime > timeout) {
27
- throw new Error('Timeout waiting for condition');
28
- }
29
- await new Promise((resolve) => setTimeout(resolve, 50));
30
- }
31
- }
32
-
33
- /**
34
- * Mock localStorage
35
- */
36
- export function mockLocalStorage() {
37
- const store: Record<string, string> = {};
38
-
39
- return {
40
- getItem: (key: string) => store[key] || null,
41
- setItem: (key: string, value: string) => {
42
- store[key] = value;
43
- },
44
- removeItem: (key: string) => {
45
- delete store[key];
46
- },
47
- clear: () => {
48
- Object.keys(store).forEach((key) => delete store[key]);
49
- },
50
- get length() {
51
- return Object.keys(store).length;
52
- },
53
- key: (index: number) => Object.keys(store)[index] || null,
54
- };
55
- }
56
-
57
- /**
58
- * Create mock JWT token
59
- */
60
- export function createMockJWT(payload: Record<string, any>, exp?: number): string {
61
- const header = btoa(JSON.stringify({ alg: 'HS256', typ: 'JWT' }));
62
- const body = btoa(
63
- JSON.stringify({
64
- ...payload,
65
- exp: exp || Math.floor(Date.now() / 1000) + 3600,
66
- iat: Math.floor(Date.now() / 1000),
67
- })
68
- );
69
- const signature = btoa('mock-signature');
70
- return `${header}.${body}.${signature}`;
71
- }
72
-
73
- /**
74
- * Sleep utility for tests
75
- */
76
- export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
77
-
78
- /**
79
- * Mock fetch response
80
- */
81
- export function mockFetchResponse(data: any, status = 200) {
82
- return Promise.resolve({
83
- ok: status >= 200 && status < 300,
84
- status,
85
- json: () => Promise.resolve(data),
86
- text: () => Promise.resolve(JSON.stringify(data)),
87
- headers: new Headers(),
88
- } as Response);
89
- }
@@ -1,212 +0,0 @@
1
- /**
2
- * Utilidades compartidas para tests de useSession
3
- * Incluye mocks, factories y wrappers
4
- */
5
-
6
- import React from 'react';
7
- import { vi } from 'vitest';
8
- import { TokenData } from '../../../src/utils/tokenStorage';
9
-
10
- // =============================
11
- // MOCK FACTORIES
12
- // =============================
13
-
14
- /**
15
- * Crea datos de token mock para tests
16
- */
17
- export function createMockTokens(overrides?: Partial<TokenData>): TokenData {
18
- const now = Date.now();
19
- return {
20
- accessToken: 'mock-access-token',
21
- refreshToken: 'mock-refresh-token',
22
- expiresAt: now + 15 * 60 * 1000, // 15 minutos
23
- refreshExpiresAt: now + 7 * 24 * 60 * 60 * 1000, // 7 días
24
- ...overrides,
25
- };
26
- }
27
-
28
- /**
29
- * Crea tokens expirados para tests
30
- */
31
- export function createExpiredTokens(): TokenData {
32
- const now = Date.now();
33
- return {
34
- accessToken: 'expired-access-token',
35
- refreshToken: 'expired-refresh-token',
36
- expiresAt: now - 1000, // Ya expiró
37
- refreshExpiresAt: now + 7 * 24 * 60 * 60 * 1000,
38
- };
39
- }
40
-
41
- /**
42
- * Crea tokens que expiran pronto para tests
43
- */
44
- export function createExpiringSoonTokens(): TokenData {
45
- const now = Date.now();
46
- return {
47
- accessToken: 'expiring-access-token',
48
- refreshToken: 'expiring-refresh-token',
49
- expiresAt: now + 2 * 60 * 1000, // 2 minutos (menos de 5)
50
- refreshExpiresAt: now + 7 * 24 * 60 * 60 * 1000,
51
- };
52
- }
53
-
54
- // =============================
55
- // MOCK SESSION MANAGER
56
- // =============================
57
-
58
- export function createMockSessionManager() {
59
- return {
60
- getInstance: vi.fn(),
61
- initialize: vi.fn().mockResolvedValue(undefined),
62
- login: vi.fn().mockResolvedValue({ success: true, tokens: createMockTokens() }),
63
- logout: vi.fn().mockResolvedValue(undefined),
64
- refreshTokens: vi.fn().mockResolvedValue(true),
65
- refreshTokensSilent: vi.fn().mockResolvedValue(true),
66
- getTokenInfo: vi.fn().mockResolvedValue({
67
- crudifyTokens: {
68
- accessToken: 'mock-access-token',
69
- refreshToken: 'mock-refresh-token',
70
- expiresAt: Date.now() + 15 * 60 * 1000,
71
- refreshExpiresAt: Date.now() + 7 * 24 * 60 * 60 * 1000,
72
- expiresIn: 15 * 60 * 1000,
73
- },
74
- }),
75
- isAuthenticated: vi.fn().mockResolvedValue(true),
76
- isRefreshing: vi.fn().mockReturnValue(false),
77
- updateLastActivity: vi.fn(),
78
- setupResponseInterceptor: vi.fn(),
79
- getTimeSinceLastActivity: vi.fn().mockReturnValue(0),
80
- clearSession: vi.fn().mockResolvedValue(undefined),
81
- // ✅ FASE 5: Nuevo método para verificar sesión activa
82
- getIsSessionActive: vi.fn().mockReturnValue(true),
83
- };
84
- }
85
-
86
- // =============================
87
- // MOCK TOKEN STORAGE
88
- // =============================
89
-
90
- export function createMockTokenStorage() {
91
- const subscribers: Array<(tokens: TokenData | null, eventType: string, hadPreviousTokens: boolean) => void> = [];
92
-
93
- return {
94
- saveTokens: vi.fn().mockResolvedValue(undefined),
95
- getTokens: vi.fn().mockResolvedValue(createMockTokens()),
96
- clearTokens: vi.fn().mockResolvedValue(undefined),
97
- hasValidTokens: vi.fn().mockResolvedValue(true),
98
- getExpirationInfo: vi.fn().mockResolvedValue({
99
- expiresAt: Date.now() + 15 * 60 * 1000,
100
- refreshExpiresAt: Date.now() + 7 * 24 * 60 * 60 * 1000,
101
- }),
102
- subscribeToChanges: vi.fn((callback) => {
103
- subscribers.push(callback);
104
- return () => {
105
- const index = subscribers.indexOf(callback);
106
- if (index > -1) {
107
- subscribers.splice(index, 1);
108
- }
109
- };
110
- }),
111
- SYNC_EVENTS: {
112
- TOKENS_CLEARED: 'TOKENS_CLEARED',
113
- TOKENS_UPDATED: 'TOKENS_UPDATED',
114
- },
115
- // Helper para simular eventos en tests
116
- _emitEvent: (tokens: TokenData | null, eventType: string, hadPreviousTokens: boolean) => {
117
- subscribers.forEach((cb) => cb(tokens, eventType, hadPreviousTokens));
118
- },
119
- };
120
- }
121
-
122
- // =============================
123
- // MOCK AUTH EVENT BUS
124
- // =============================
125
-
126
- export function createMockAuthEventBus() {
127
- const subscribers: Array<(event: { type: string; details?: Record<string, unknown> }) => void> = [];
128
-
129
- return {
130
- subscribe: vi.fn((callback) => {
131
- subscribers.push(callback);
132
- return () => {
133
- const index = subscribers.indexOf(callback);
134
- if (index > -1) {
135
- subscribers.splice(index, 1);
136
- }
137
- };
138
- }),
139
- emit: vi.fn(),
140
- // Helper para simular eventos en tests
141
- _emitEvent: (type: string, details?: Record<string, unknown>) => {
142
- subscribers.forEach((cb) => cb({ type, details }));
143
- },
144
- };
145
- }
146
-
147
- // =============================
148
- // MOCK NAVIGATION TRACKER
149
- // =============================
150
-
151
- export function createMockNavigationTracker() {
152
- const subscribers: Array<() => void> = [];
153
-
154
- return {
155
- getInstance: vi.fn().mockReturnThis(),
156
- subscribe: vi.fn((callback) => {
157
- subscribers.push(callback);
158
- return () => {
159
- const index = subscribers.indexOf(callback);
160
- if (index > -1) {
161
- subscribers.splice(index, 1);
162
- }
163
- };
164
- }),
165
- // Helper para simular navegación en tests
166
- _emitNavigation: () => {
167
- subscribers.forEach((cb) => cb());
168
- },
169
- };
170
- }
171
-
172
- // =============================
173
- // REACT WRAPPER
174
- // =============================
175
-
176
- /**
177
- * Wrapper para tests de hooks con React
178
- */
179
- export function createWrapper() {
180
- return function Wrapper({ children }: { children: React.ReactNode }) {
181
- return <>{children}</>;
182
- };
183
- }
184
-
185
- // =============================
186
- // WAIT UTILITIES
187
- // =============================
188
-
189
- /**
190
- * Espera un tiempo específico
191
- */
192
- export function wait(ms: number): Promise<void> {
193
- return new Promise((resolve) => setTimeout(resolve, ms));
194
- }
195
-
196
- /**
197
- * Espera hasta que una condición sea verdadera
198
- */
199
- export async function waitFor(
200
- condition: () => boolean,
201
- options: { timeout?: number; interval?: number } = {}
202
- ): Promise<void> {
203
- const { timeout = 5000, interval = 50 } = options;
204
- const startTime = Date.now();
205
-
206
- while (!condition()) {
207
- if (Date.now() - startTime > timeout) {
208
- throw new Error('waitFor timeout');
209
- }
210
- await wait(interval);
211
- }
212
- }
package/tests/setup.ts DELETED
@@ -1,139 +0,0 @@
1
- /**
2
- * Test Setup File
3
- * Configures the testing environment with all necessary mocks and utilities
4
- */
5
-
6
- import { afterEach, beforeEach, vi } from 'vitest';
7
- import { cleanup } from '@testing-library/react';
8
- import '@testing-library/jest-dom/vitest';
9
-
10
- // Mock window.history para tests
11
- const originalPushState = window.history.pushState;
12
- const originalReplaceState = window.history.replaceState;
13
-
14
- beforeEach(() => {
15
- // Restaurar métodos originales antes de cada test
16
- window.history.pushState = originalPushState;
17
- window.history.replaceState = originalReplaceState;
18
- });
19
-
20
- // Cleanup after each test case
21
- afterEach(() => {
22
- cleanup();
23
- localStorage.clear();
24
- sessionStorage.clear();
25
- vi.clearAllMocks();
26
-
27
- // Cleanup después de cada test
28
- window.history.pushState = originalPushState;
29
- window.history.replaceState = originalReplaceState;
30
- });
31
-
32
- // Mock window.matchMedia
33
- Object.defineProperty(window, 'matchMedia', {
34
- writable: true,
35
- value: vi.fn().mockImplementation((query) => ({
36
- matches: false,
37
- media: query,
38
- onchange: null,
39
- addListener: vi.fn(),
40
- removeListener: vi.fn(),
41
- addEventListener: vi.fn(),
42
- removeEventListener: vi.fn(),
43
- dispatchEvent: vi.fn(),
44
- })),
45
- });
46
-
47
- // Mock IntersectionObserver
48
- (globalThis as any).IntersectionObserver = class IntersectionObserver {
49
- constructor() {}
50
- disconnect() {}
51
- observe() {}
52
- takeRecords() {
53
- return [];
54
- }
55
- unobserve() {}
56
- };
57
-
58
- // Mock crypto for UUID generation and Web Crypto API
59
- // The subtle mock provides functional encryption/decryption for tests
60
- const mockSubtle = {
61
- // SHA-256 digest - returns deterministic hash based on input
62
- digest: async (_algorithm: string, data: ArrayBuffer): Promise<ArrayBuffer> => {
63
- const input = new Uint8Array(data);
64
- const result = new Uint8Array(32);
65
- // Simple deterministic "hash" for testing - XOR bytes into result
66
- for (let i = 0; i < input.length; i++) {
67
- result[i % 32] ^= input[i];
68
- }
69
- return result.buffer;
70
- },
71
-
72
- // Import key material for PBKDF2
73
- importKey: async (
74
- _format: string,
75
- _keyData: ArrayBuffer,
76
- _algorithm: string,
77
- _extractable: boolean,
78
- _keyUsages: string[]
79
- ): Promise<CryptoKey> => {
80
- return { type: 'secret' } as CryptoKey;
81
- },
82
-
83
- // Derive key using PBKDF2
84
- deriveKey: async (
85
- _algorithm: object,
86
- _baseKey: CryptoKey,
87
- _derivedKeyType: object,
88
- _extractable: boolean,
89
- _keyUsages: string[]
90
- ): Promise<CryptoKey> => {
91
- return { type: 'secret' } as CryptoKey;
92
- },
93
-
94
- // AES-GCM encrypt - simple XOR for reversible mock encryption
95
- encrypt: async (
96
- _algorithm: { name: string; iv: Uint8Array },
97
- _key: CryptoKey,
98
- data: ArrayBuffer
99
- ): Promise<ArrayBuffer> => {
100
- const input = new Uint8Array(data);
101
- const output = new Uint8Array(input.length);
102
- for (let i = 0; i < input.length; i++) {
103
- output[i] = input[i] ^ 42; // Simple XOR with constant
104
- }
105
- return output.buffer;
106
- },
107
-
108
- // AES-GCM decrypt - reverse of encrypt
109
- decrypt: async (
110
- _algorithm: { name: string; iv: Uint8Array },
111
- _key: CryptoKey,
112
- data: ArrayBuffer
113
- ): Promise<ArrayBuffer> => {
114
- const input = new Uint8Array(data);
115
- const output = new Uint8Array(input.length);
116
- for (let i = 0; i < input.length; i++) {
117
- output[i] = input[i] ^ 42; // XOR with same constant reverses encryption
118
- }
119
- return output.buffer;
120
- },
121
- };
122
-
123
- Object.defineProperty(globalThis, 'crypto', {
124
- value: {
125
- randomUUID: () => 'test-uuid-' + Math.random().toString(36).substring(2, 15),
126
- getRandomValues: (arr: Uint8Array) => {
127
- for (let i = 0; i < arr.length; i++) {
128
- arr[i] = Math.floor(Math.random() * 256);
129
- }
130
- return arr;
131
- },
132
- subtle: mockSubtle,
133
- },
134
- });
135
-
136
- // Global test timeout
137
- vi.setConfig({ testTimeout: 10000 });
138
-
139
- console.log('✅ Test environment setup complete');
package/tests/vitest.d.ts DELETED
@@ -1 +0,0 @@
1
- /// <reference types="vitest/globals" />
package/vitest.config.ts DELETED
@@ -1,39 +0,0 @@
1
- import { defineConfig } from 'vitest/config';
2
- import path from 'path';
3
-
4
- export default defineConfig({
5
- test: {
6
- globals: true,
7
- environment: 'jsdom',
8
- setupFiles: ['./tests/setup.ts'],
9
- include: ['tests/**/*.test.{ts,tsx}'],
10
- testTimeout: 10000, // 10 seconds timeout for tests
11
- hookTimeout: 10000, // 10 seconds timeout for hooks
12
- pool: 'forks', // Use forks pool for better isolation in CI
13
- poolOptions: {
14
- forks: {
15
- singleFork: true, // Use single fork to reduce memory usage
16
- },
17
- },
18
- coverage: {
19
- provider: 'v8',
20
- reporter: ['text', 'json', 'html', 'lcov'],
21
- include: ['src/**/*.{ts,tsx}'],
22
- exclude: [
23
- 'node_modules/',
24
- 'tests/',
25
- 'dist/',
26
- '**/*.d.ts',
27
- '**/*.config.*',
28
- '**/mockData.ts',
29
- '**/testUtils.tsx',
30
- '**/testUtils.ts',
31
- ],
32
- },
33
- },
34
- resolve: {
35
- alias: {
36
- '@': path.resolve(__dirname, './src'),
37
- },
38
- },
39
- });