@c.a.f/testing 1.0.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.
Files changed (50) hide show
  1. package/.build/__tests__/react/renderWithCAF.spec.d.ts +1 -0
  2. package/.build/__tests__/react/renderWithCAF.spec.js +53 -0
  3. package/.build/index.d.ts +1 -0
  4. package/.build/index.js +1 -0
  5. package/.build/src/core/IntegrationTestHelpers.d.ts +77 -0
  6. package/.build/src/core/IntegrationTestHelpers.js +78 -0
  7. package/.build/src/core/PlocTestHelpers.d.ts +133 -0
  8. package/.build/src/core/PlocTestHelpers.js +205 -0
  9. package/.build/src/core/PulseTestHelpers.d.ts +71 -0
  10. package/.build/src/core/PulseTestHelpers.js +106 -0
  11. package/.build/src/core/RepositoryTestHelpers.d.ts +48 -0
  12. package/.build/src/core/RepositoryTestHelpers.js +76 -0
  13. package/.build/src/core/RouteTestHelpers.d.ts +67 -0
  14. package/.build/src/core/RouteTestHelpers.js +94 -0
  15. package/.build/src/core/UseCaseTestHelpers.d.ts +100 -0
  16. package/.build/src/core/UseCaseTestHelpers.js +161 -0
  17. package/.build/src/core/index.d.ts +6 -0
  18. package/.build/src/core/index.js +6 -0
  19. package/.build/src/i18n/I18nTestHelpers.d.ts +76 -0
  20. package/.build/src/i18n/I18nTestHelpers.js +122 -0
  21. package/.build/src/i18n/index.d.ts +1 -0
  22. package/.build/src/i18n/index.js +1 -0
  23. package/.build/src/index.d.ts +5 -0
  24. package/.build/src/index.js +10 -0
  25. package/.build/src/permission/PermissionTestHelpers.d.ts +75 -0
  26. package/.build/src/permission/PermissionTestHelpers.js +121 -0
  27. package/.build/src/permission/index.d.ts +1 -0
  28. package/.build/src/permission/index.js +1 -0
  29. package/.build/src/react/createTestPloc.d.ts +19 -0
  30. package/.build/src/react/createTestPloc.js +21 -0
  31. package/.build/src/react/index.d.ts +12 -0
  32. package/.build/src/react/index.js +12 -0
  33. package/.build/src/react/mockUseCase.d.ts +36 -0
  34. package/.build/src/react/mockUseCase.js +44 -0
  35. package/.build/src/react/renderWithCAF.d.ts +31 -0
  36. package/.build/src/react/renderWithCAF.js +23 -0
  37. package/.build/src/react/waitForPlocState.d.ts +22 -0
  38. package/.build/src/react/waitForPlocState.js +24 -0
  39. package/.build/src/validation/ValidationTestHelpers.d.ts +66 -0
  40. package/.build/src/validation/ValidationTestHelpers.js +118 -0
  41. package/.build/src/validation/index.d.ts +1 -0
  42. package/.build/src/validation/index.js +1 -0
  43. package/.build/src/workflow/WorkflowTestHelpers.d.ts +75 -0
  44. package/.build/src/workflow/WorkflowTestHelpers.js +146 -0
  45. package/.build/src/workflow/index.d.ts +1 -0
  46. package/.build/src/workflow/index.js +1 -0
  47. package/.build/vitest.config.d.ts +7 -0
  48. package/.build/vitest.config.js +6 -0
  49. package/README.md +503 -0
  50. package/package.json +87 -0
package/README.md ADDED
@@ -0,0 +1,503 @@
1
+ # @c.a.f/testing
2
+
3
+ Testing utilities and helpers for CAF applications. Provides mocks, test helpers, and utilities for testing UseCase, Ploc, Pulse, Workflow, Permission, I18n, and Validation.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @c.a.f/testing --save-dev
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Core Testing Utilities
14
+
15
+ #### Testing Ploc
16
+
17
+ ```typescript
18
+ import { createPlocTester, waitForStateChange } from '@c.a.f/testing/core';
19
+ import { Ploc } from '@c.a.f/core';
20
+
21
+ class CounterPloc extends Ploc<number> {
22
+ constructor() {
23
+ super(0);
24
+ }
25
+ increment() {
26
+ this.changeState(this.state + 1);
27
+ }
28
+ }
29
+
30
+ describe('CounterPloc', () => {
31
+ it('tracks state changes', () => {
32
+ const ploc = new CounterPloc();
33
+ const tester = createPlocTester(ploc);
34
+
35
+ ploc.increment();
36
+ ploc.increment();
37
+
38
+ expect(tester.getStateChangeCount()).toBe(2);
39
+ expect(tester.getStateHistory()).toEqual([0, 1, 2]);
40
+ expect(tester.getLastStateChange()).toBe(2);
41
+
42
+ tester.cleanup();
43
+ });
44
+
45
+ it('waits for state change', async () => {
46
+ const ploc = new CounterPloc();
47
+
48
+ setTimeout(() => ploc.increment(), 100);
49
+ const finalState = await waitForStateChange(ploc, (state) => state === 1);
50
+
51
+ expect(finalState).toBe(1);
52
+ });
53
+ });
54
+ ```
55
+
56
+ #### Testing Pulse
57
+
58
+ ```typescript
59
+ import { createPulseTester, waitForPulseValue } from '@c.a.f/testing/core';
60
+ import { pulse } from '@c.a.f/core';
61
+
62
+ describe('Pulse', () => {
63
+ it('tracks value changes', () => {
64
+ const count = pulse(0);
65
+ const tester = createPulseTester(count);
66
+
67
+ count.value = 5;
68
+ count.value = 10;
69
+
70
+ expect(tester.getValueChangeCount()).toBe(2);
71
+ expect(tester.getValueHistory()).toEqual([0, 5, 10]);
72
+ expect(tester.getLastValueChange()).toBe(10);
73
+
74
+ tester.cleanup();
75
+ });
76
+
77
+ it('waits for pulse value', async () => {
78
+ const count = pulse(0);
79
+
80
+ setTimeout(() => { count.value = 5; }, 100);
81
+ const finalValue = await waitForPulseValue(count, (value) => value === 5);
82
+
83
+ expect(finalValue).toBe(5);
84
+ });
85
+ });
86
+ ```
87
+
88
+ #### Testing UseCase
89
+
90
+ ```typescript
91
+ import {
92
+ createMockUseCase,
93
+ createMockUseCaseSuccess,
94
+ createMockUseCaseError,
95
+ createUseCaseTester,
96
+ createSuccessResult,
97
+ } from '@c.a.f/testing/core';
98
+ import { UseCase } from '@c.a.f/core';
99
+
100
+ describe('UseCase', () => {
101
+ it('creates and tests mock use case', async () => {
102
+ const mockUseCase = createMockUseCase<[], string>(() =>
103
+ createSuccessResult('result')
104
+ );
105
+ const tester = createUseCaseTester(mockUseCase);
106
+
107
+ const result = await tester.execute([]);
108
+ expect(result.data.value).toBe('result');
109
+ expect(result.error.value).toBeNull();
110
+ });
111
+
112
+ it('uses success shortcut', async () => {
113
+ const useCase = createMockUseCaseSuccess([{ id: '1', name: 'John' }]);
114
+ const result = await useCase.execute();
115
+ expect(result.data.value).toEqual([{ id: '1', name: 'John' }]);
116
+ });
117
+
118
+ it('uses error shortcut', async () => {
119
+ const useCase = createMockUseCaseError(new Error('Failed'));
120
+ const result = await useCase.execute();
121
+ expect(result.error.value?.message).toBe('Failed');
122
+ });
123
+
124
+ it('executes and gets data', async () => {
125
+ const mockUseCase = createMockUseCase<[number], number>((count) =>
126
+ createSuccessResult(count * 2)
127
+ );
128
+ const tester = createUseCaseTester(mockUseCase);
129
+
130
+ const data = await tester.executeAndGetData([5]);
131
+ expect(data).toBe(10);
132
+ });
133
+ });
134
+ ```
135
+
136
+ #### Mock Ploc and state history (snapshot)
137
+
138
+ ```typescript
139
+ import {
140
+ createMockPloc,
141
+ createPlocTester,
142
+ assertStateHistory,
143
+ getStateHistorySnapshot,
144
+ } from '@c.a.f/testing/core';
145
+
146
+ it('mock Ploc and state history', () => {
147
+ const ploc = createMockPloc({ count: 0 });
148
+ const tester = createPlocTester(ploc);
149
+
150
+ ploc.changeState({ count: 1 });
151
+ ploc.changeState({ count: 2 });
152
+
153
+ assertStateHistory(tester, [{ count: 0 }, { count: 1 }, { count: 2 }]);
154
+ expect(getStateHistorySnapshot(tester)).toMatchSnapshot();
155
+ tester.cleanup();
156
+ });
157
+ ```
158
+
159
+ #### Mock Repository (domain I*Repository)
160
+
161
+ ```typescript
162
+ import { createMockRepository, createMockRepositoryStub } from '@c.a.f/testing/core';
163
+ import type { IUserRepository } from '../domain';
164
+
165
+ it('mocks repository', async () => {
166
+ const repo = createMockRepository<IUserRepository>({
167
+ getUsers: async () => [{ id: '1', name: 'John' }],
168
+ getUserById: async (id) => ({ id, name: 'User ' + id }),
169
+ });
170
+
171
+ expect(await repo.getUsers()).toHaveLength(1);
172
+ expect((await repo.getUserById('2'))?.name).toBe('User 2');
173
+ });
174
+
175
+ it('stub and spy', async () => {
176
+ const stub = createMockRepositoryStub<IUserRepository>();
177
+ stub.getUsers = vi.fn().mockResolvedValue([]);
178
+ await stub.getUsers();
179
+ expect(stub.getUsers).toHaveBeenCalledTimes(1);
180
+ });
181
+ ```
182
+
183
+ #### Integration test helpers
184
+
185
+ ```typescript
186
+ import {
187
+ createPlocUseCaseContext,
188
+ flushPromises,
189
+ } from '@c.a.f/testing/core';
190
+
191
+ it('integration context', async () => {
192
+ const { ploc, useCase } = createPlocUseCaseContext(
193
+ { items: [], loading: false },
194
+ [{ id: '1', name: 'Item' }]
195
+ );
196
+ // Use with CAFProvider or pass as props
197
+ expect(ploc.state.loading).toBe(false);
198
+ const result = await useCase.execute();
199
+ expect(result.data.value).toHaveLength(1);
200
+ await flushPromises();
201
+ });
202
+ ```
203
+
204
+ ### React Testing Utilities (`@c.a.f/testing/react`)
205
+
206
+ Use these when testing React components that use `usePlocFromContext`, `useUseCaseFromContext`, or `usePloc` / `useUseCase` with context-provided instances.
207
+
208
+ **Requirements:** `react` and `@testing-library/react` (peer dependencies). Install in your app:
209
+
210
+ ```bash
211
+ npm install react @testing-library/react
212
+ ```
213
+
214
+ #### renderWithCAF
215
+
216
+ Render a component wrapped in `CAFProvider` so Ploc/UseCase context is available:
217
+
218
+ ```tsx
219
+ import React from 'react';
220
+ import { screen } from '@testing-library/react';
221
+ import { renderWithCAF, createTestPloc, mockUseCase } from '@c.a.f/testing/react';
222
+ import { usePlocFromContext, usePloc } from '@c.a.f/infrastructure-react';
223
+
224
+ const Counter = () => {
225
+ const ploc = usePlocFromContext('counter');
226
+ if (!ploc) return null;
227
+ const [state] = usePloc(ploc);
228
+ return <span data-testid="count">{state.count}</span>;
229
+ };
230
+
231
+ it('renders with CAF context', () => {
232
+ const ploc = createTestPloc({ count: 5 });
233
+ renderWithCAF(<Counter />, { plocs: { counter: ploc } });
234
+ expect(screen.getByTestId('count')).toHaveTextContent('5');
235
+ });
236
+ ```
237
+
238
+ #### createTestPloc
239
+
240
+ Create a Ploc with controllable state (no business logic). Same idea as `createMockPloc` from core, for use in React tests:
241
+
242
+ ```tsx
243
+ const ploc = createTestPloc({ count: 0 });
244
+ renderWithCAF(<Counter />, { plocs: { counter: ploc } });
245
+ ploc.changeState({ count: 1 });
246
+ expect(screen.getByTestId('count')).toHaveTextContent('1');
247
+ ```
248
+
249
+ #### waitForPlocState
250
+
251
+ Wait for a Ploc to reach a state matching a predicate (e.g. after an async update):
252
+
253
+ ```tsx
254
+ const ploc = createTestPloc({ loading: true, items: [] });
255
+ renderWithCAF(<List />, { plocs: { list: ploc } });
256
+ ploc.changeState({ loading: false, items: [{ id: '1' }] });
257
+ await waitForPlocState(ploc, (state) => !state.loading && state.items.length > 0);
258
+ expect(screen.getByText('1')).toBeInTheDocument();
259
+ ```
260
+
261
+ #### mockUseCase
262
+
263
+ Create mock UseCases for context:
264
+
265
+ ```tsx
266
+ const submit = mockUseCase.success({ id: '1' });
267
+ const load = mockUseCase.error(new Error('Network error'));
268
+ const search = mockUseCase.async([{ id: '1' }], 50); // resolves after 50ms
269
+
270
+ renderWithCAF(<Form />, { useCases: { submit, load, search } });
271
+ ```
272
+
273
+ - `mockUseCase.success(data)` — always returns success with `data`
274
+ - `mockUseCase.error(error)` — always returns `error`
275
+ - `mockUseCase.async(data, delayMs?)` — resolves with `data` after optional delay
276
+ - `mockUseCase.fn(implementation)` — custom implementation (same as `createMockUseCase` from core)
277
+
278
+ #### Testing RouteManager
279
+
280
+ ```typescript
281
+ import { createMockRouteRepository, createRouteManagerTester } from '@c.a.f/testing/core';
282
+ import { RouteManager } from '@c.a.f/core';
283
+
284
+ describe('RouteManager', () => {
285
+ it('tracks route changes', async () => {
286
+ const mockRepo = createMockRouteRepository();
287
+ const routeManager = new RouteManager(mockRepo);
288
+ const tester = createRouteManagerTester(routeManager);
289
+
290
+ await tester.changeRoute('/dashboard');
291
+ expect(tester.getCurrentRoute()).toBe('/dashboard');
292
+ expect(tester.getRouteHistory()).toContain('/dashboard');
293
+ });
294
+ });
295
+ ```
296
+
297
+ ### Workflow Testing Utilities
298
+
299
+ ```typescript
300
+ import { createWorkflowTester, waitForWorkflowState } from '@c.a.f/testing/workflow';
301
+ import { WorkflowManager, WorkflowDefinition } from '@c.a.f/workflow';
302
+
303
+ describe('Workflow', () => {
304
+ it('tracks workflow state changes', async () => {
305
+ const workflow = new WorkflowManager(definition);
306
+ const tester = createWorkflowTester(workflow);
307
+
308
+ await tester.dispatch('approve');
309
+ await waitForWorkflowState(workflow, 'approved');
310
+
311
+ expect(tester.getCurrentState()).toBe('approved');
312
+ expect(tester.getStateHistory().length).toBeGreaterThan(1);
313
+
314
+ tester.cleanup();
315
+ });
316
+
317
+ it('waits for final state', async () => {
318
+ const workflow = new WorkflowManager(definition);
319
+
320
+ await workflow.dispatch('complete');
321
+ const finalState = await waitForFinalState(workflow);
322
+
323
+ expect(finalState.isFinal).toBe(true);
324
+ });
325
+ });
326
+ ```
327
+
328
+ ### Permission Testing Utilities
329
+
330
+ ```typescript
331
+ import { createMockPermissionChecker, createPermissionTester } from '@c.a.f/testing/permission';
332
+ import { PermissionManager } from '@c.a.f/permission';
333
+
334
+ describe('Permission', () => {
335
+ it('tests permission checking', async () => {
336
+ const mockChecker = createMockPermissionChecker(['user.edit', 'post.create']);
337
+ const manager = new PermissionManager(mockChecker);
338
+ const tester = createPermissionTester(manager);
339
+
340
+ expect(await tester.hasPermission('user.edit')).toBe(true);
341
+ expect(await tester.hasPermission('user.delete')).toBe(false);
342
+ expect(await tester.hasAnyPermission(['user.edit', 'user.delete'])).toBe(true);
343
+ });
344
+
345
+ it('modifies permissions dynamically', () => {
346
+ const mockChecker = createMockPermissionChecker(['user.view']);
347
+
348
+ mockChecker.addPermission('user.edit');
349
+ expect(mockChecker.check('user.edit').granted).toBe(true);
350
+
351
+ mockChecker.removePermission('user.view');
352
+ expect(mockChecker.check('user.view').granted).toBe(false);
353
+ });
354
+ });
355
+ ```
356
+
357
+ ### I18n Testing Utilities
358
+
359
+ ```typescript
360
+ import { createMockTranslator, createTranslationTester } from '@c.a.f/testing/i18n';
361
+ import { TranslationManager } from '@c.a.f/i18n';
362
+
363
+ describe('I18n', () => {
364
+ it('tests translation', () => {
365
+ const mockTranslator = createMockTranslator({
366
+ en: { greeting: 'Hello', welcome: 'Welcome {{name}}' },
367
+ fa: { greeting: 'سلام', welcome: 'خوش آمدید {{name}}' },
368
+ });
369
+ const manager = new TranslationManager(mockTranslator);
370
+ const tester = createTranslationTester(manager);
371
+
372
+ expect(tester.t('greeting')).toBe('Hello');
373
+ expect(tester.translateWithValues('welcome', { name: 'John' })).toBe('Welcome John');
374
+ });
375
+
376
+ it('tests language switching', async () => {
377
+ const mockTranslator = createMockTranslator({
378
+ en: { greeting: 'Hello' },
379
+ fa: { greeting: 'سلام' },
380
+ });
381
+ const manager = new TranslationManager(mockTranslator);
382
+ const tester = createTranslationTester(manager);
383
+
384
+ expect(tester.getCurrentLanguage()).toBe('en');
385
+ await tester.changeLanguage('fa');
386
+ expect(tester.getCurrentLanguage()).toBe('fa');
387
+ expect(tester.t('greeting')).toBe('سلام');
388
+ });
389
+ });
390
+ ```
391
+
392
+ ### Validation Testing Utilities
393
+
394
+ ```typescript
395
+ import { createMockValidator, createValidationTester } from '@c.a.f/testing/validation';
396
+
397
+ describe('Validation', () => {
398
+ it('tests validation', async () => {
399
+ const mockValidator = createMockValidator((data: any) => {
400
+ return data.email && data.email.includes('@');
401
+ });
402
+ const tester = createValidationTester(mockValidator);
403
+
404
+ const successResult = await tester.expectSuccess({ email: 'test@example.com' });
405
+ expect(successResult.email).toBe('test@example.com');
406
+
407
+ const errors = await tester.expectFailure({ email: 'invalid' });
408
+ expect(errors.length).toBeGreaterThan(0);
409
+ });
410
+ });
411
+ ```
412
+
413
+ ## Exports
414
+
415
+ ### Core Testing (`@c.a.f/testing/core`)
416
+
417
+ - `PlocTester` — Tester for Ploc instances
418
+ - `createPlocTester` — Create a Ploc tester
419
+ - `createMockPloc` — Create a Ploc with controllable state (no logic)
420
+ - `MockPloc` — Concrete Ploc class for tests
421
+ - `waitForStateChange` — Wait for state change matching predicate
422
+ - `waitForStateChanges` — Wait for specific number of state changes
423
+ - `assertStateHistory` — Assert state history matches expected (snapshot-style)
424
+ - `getStateHistorySnapshot` / `getStateHistorySnapshotJson` — Snapshot state history
425
+ - `PulseTester` — Tester for Pulse instances
426
+ - `createPulseTester` — Create a Pulse tester
427
+ - `waitForPulseValue` — Wait for pulse value matching predicate
428
+ - `MockUseCase` — Mock UseCase implementation
429
+ - `createMockUseCase` — Create a mock UseCase
430
+ - `createMockUseCaseSuccess` — Mock UseCase that returns success with data
431
+ - `createMockUseCaseError` — Mock UseCase that returns an error
432
+ - `createMockUseCaseAsync` — Mock UseCase that resolves after optional delay
433
+ - `UseCaseTester` — Tester for UseCase instances
434
+ - `createUseCaseTester` — Create a UseCase tester
435
+ - `createSuccessResult` — Create successful RequestResult
436
+ - `createErrorResult` — Create failed RequestResult
437
+ - `createLoadingResult` — Create loading RequestResult
438
+ - `createMockRepository` — Generic stub for domain I*Repository interfaces
439
+ - `createMockRepositoryStub` — Empty repository stub (assign or spy methods)
440
+ - `flushPromises` — Resolve pending microtasks in integration tests
441
+ - `runWithFakeTimers` — Placeholder for running code with fake timers
442
+ - `createPlocUseCaseContext` — Minimal Ploc + UseCase context for integration tests
443
+ - `MockRouteRepository` — Mock RouteRepository implementation
444
+ - `createMockRouteRepository` — Create a mock RouteRepository
445
+ - `RouteManagerTester` — Tester for RouteManager instances
446
+ - `createRouteManagerTester` — Create a RouteManager tester
447
+
448
+ ### Workflow Testing (`@c.a.f/testing/workflow`)
449
+
450
+ - `WorkflowTester` — Tester for WorkflowManager instances
451
+ - `createWorkflowTester` — Create a Workflow tester
452
+ - `waitForWorkflowState` — Wait for workflow to reach specific state
453
+ - `waitForFinalState` — Wait for workflow to reach final state
454
+
455
+ ### Permission Testing (`@c.a.f/testing/permission`)
456
+
457
+ - `MockPermissionChecker` — Mock PermissionChecker implementation
458
+ - `createMockPermissionChecker` — Create a mock PermissionChecker
459
+ - `PermissionTester` — Tester for PermissionManager instances
460
+ - `createPermissionTester` — Create a Permission tester
461
+
462
+ ### I18n Testing (`@c.a.f/testing/i18n`)
463
+
464
+ - `MockTranslator` — Mock Translator implementation
465
+ - `createMockTranslator` — Create a mock Translator
466
+ - `TranslationTester` — Tester for TranslationManager instances
467
+ - `createTranslationTester` — Create a Translation tester
468
+
469
+ ### Validation Testing (`@c.a.f/testing/validation`)
470
+
471
+ - `MockValidator` — Mock Validator implementation
472
+ - `createMockValidator` — Create a mock Validator
473
+ - `ValidationTester` — Tester for Validator instances
474
+ - `createValidationTester` — Create a Validation tester
475
+ - `expectSuccess` — Validate and expect success
476
+ - `expectFailure` — Validate and expect failure
477
+
478
+ ### React Testing (`@c.a.f/testing/react`)
479
+
480
+ - `renderWithCAF` — Render with CAFProvider (Ploc/UseCase context)
481
+ - `RenderWithCAFOptions` — Options for renderWithCAF (plocs, useCases, and RTL options)
482
+ - `createTestPloc` — Create a test Ploc with controllable state
483
+ - `waitForPlocState` — Wait for Ploc state to match a predicate
484
+ - `mockUseCase` — Mock UseCase helpers: `success`, `error`, `async`, `fn`
485
+
486
+ ## Dependencies
487
+
488
+ - `@c.a.f/core` — Core primitives
489
+ - `@c.a.f/infrastructure-react` — React provider (for `@c.a.f/testing/react`)
490
+ - `@c.a.f/workflow` — Workflow package (for workflow testing utilities)
491
+ - `@c.a.f/permission` — Permission package (for permission testing utilities)
492
+ - `@c.a.f/i18n` — I18n package (for i18n testing utilities)
493
+ - `@c.a.f/validation` — Validation package (for validation testing utilities)
494
+
495
+ **React testing (`@c.a.f/testing/react`):** Peer dependencies `react` and `@testing-library/react` (optional; required only when using the react entry point).
496
+
497
+ ## Dev Dependencies
498
+
499
+ - `vitest` — Testing framework (optional, works with any testing framework)
500
+
501
+ ## License
502
+
503
+ MIT
package/package.json ADDED
@@ -0,0 +1,87 @@
1
+ {
2
+ "name": "@c.a.f/testing",
3
+ "type": "module",
4
+ "version": "1.0.0",
5
+ "description": "Testing utilities and helpers for CAF applications. Provides mocks, test helpers, and utilities for testing UseCase, Ploc, Pulse, Workflow, Permission, I18n, and Validation.",
6
+ "keywords": ["clean-architecture-frontend", "clean-architecture", "caf", "testing", "test-utils", "mocks", "test-helpers"],
7
+ "author": "ali aslani <aliaslani.mm@gmail.com>",
8
+ "license": "MIT",
9
+ "repository": "https://github.com/ialiaslani/caf.git",
10
+ "main": "./.build/index.js",
11
+ "module": "./.build/index.js",
12
+ "types": "./.build/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./.build/index.d.ts",
16
+ "import": "./.build/index.js",
17
+ "node": "./.build/index.js",
18
+ "default": "./.build/index.js"
19
+ },
20
+ "./core": {
21
+ "types": "./.build/core/index.d.ts",
22
+ "import": "./.build/core/index.js",
23
+ "node": "./.build/core/index.js",
24
+ "default": "./.build/core/index.js"
25
+ },
26
+ "./workflow": {
27
+ "types": "./.build/workflow/index.d.ts",
28
+ "import": "./.build/workflow/index.js",
29
+ "node": "./.build/workflow/index.js",
30
+ "default": "./.build/workflow/index.js"
31
+ },
32
+ "./permission": {
33
+ "types": "./.build/permission/index.d.ts",
34
+ "import": "./.build/permission/index.js",
35
+ "node": "./.build/permission/index.js",
36
+ "default": "./.build/permission/index.js"
37
+ },
38
+ "./i18n": {
39
+ "types": "./.build/i18n/index.d.ts",
40
+ "import": "./.build/i18n/index.js",
41
+ "node": "./.build/i18n/index.js",
42
+ "default": "./.build/i18n/index.js"
43
+ },
44
+ "./validation": {
45
+ "types": "./.build/validation/index.d.ts",
46
+ "import": "./.build/validation/index.js",
47
+ "node": "./.build/validation/index.js",
48
+ "default": "./.build/validation/index.js"
49
+ },
50
+ "./react": {
51
+ "types": "./.build/react/index.d.ts",
52
+ "import": "./.build/react/index.js",
53
+ "node": "./.build/react/index.js",
54
+ "default": "./.build/react/index.js"
55
+ }
56
+ },
57
+ "files": [".build"],
58
+ "scripts": {
59
+ "build": "tsc --build",
60
+ "start": "tsc --watch",
61
+ "test": "vitest run",
62
+ "test:watch": "vitest",
63
+ "prepublishOnly": "npm run build"
64
+ },
65
+ "dependencies": {
66
+ "@c.a.f/core": "1.0.3",
67
+ "@c.a.f/infrastructure-react": "^1.0.4",
68
+ "@c.a.f/workflow": "1.0.1",
69
+ "@c.a.f/permission": "1.0.0",
70
+ "@c.a.f/i18n": "1.0.0",
71
+ "@c.a.f/validation": "1.0.3"
72
+ },
73
+ "peerDependencies": {
74
+ "react": ">=16.8.0",
75
+ "@testing-library/react": ">=14.0.0"
76
+ },
77
+ "peerDependenciesMeta": {
78
+ "react": { "optional": true },
79
+ "@testing-library/react": { "optional": true }
80
+ },
81
+ "devDependencies": {
82
+ "@testing-library/react": "^16.0.0",
83
+ "happy-dom": "^15.11.7",
84
+ "react": "^18.2.0",
85
+ "vitest": "^2.1.0"
86
+ }
87
+ }