@carlonicora/nextjs-jsonapi 1.16.0 → 1.17.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 (123) hide show
  1. package/dist/ApiData-DPKNfY-9.d.mts +10 -0
  2. package/dist/ApiData-DPKNfY-9.d.ts +10 -0
  3. package/dist/ApiRequestDataTypeInterface-DIEOFn9s.d.mts +40 -0
  4. package/dist/ApiRequestDataTypeInterface-DIEOFn9s.d.ts +40 -0
  5. package/dist/{ApiResponseInterface-BvWIeLkq.d.ts → ApiResponseInterface-BKyod24U.d.ts} +2 -11
  6. package/dist/{ApiResponseInterface-CAbw0sv7.d.mts → ApiResponseInterface-Dqvu09tz.d.mts} +2 -11
  7. package/dist/{BlockNoteEditor-MBFDWP7X.js → BlockNoteEditor-34T5CY27.js} +17 -16
  8. package/dist/BlockNoteEditor-34T5CY27.js.map +1 -0
  9. package/dist/{BlockNoteEditor-HFX7Z5BQ.mjs → BlockNoteEditor-4Z6TZBJE.mjs} +7 -6
  10. package/dist/{BlockNoteEditor-HFX7Z5BQ.mjs.map → BlockNoteEditor-4Z6TZBJE.mjs.map} +1 -1
  11. package/dist/JsonApiContext-Bsm_Q2oe.d.mts +41 -0
  12. package/dist/JsonApiContext-Bsm_Q2oe.d.ts +41 -0
  13. package/dist/JsonApiRequest-54ZBO7WQ.js +24 -0
  14. package/dist/{JsonApiRequest-45CLE65I.js.map → JsonApiRequest-54ZBO7WQ.js.map} +1 -1
  15. package/dist/{JsonApiRequest-6IPS3DZJ.mjs → JsonApiRequest-XWQWTFEQ.mjs} +2 -2
  16. package/dist/chunk-3EPNHTMH.js +26 -0
  17. package/dist/chunk-3EPNHTMH.js.map +1 -0
  18. package/dist/{chunk-BCKYJQ3K.mjs → chunk-3VM3WAOV.mjs} +1 -1
  19. package/dist/{chunk-R5QSSISB.js → chunk-7DTKRMYW.js} +21 -14
  20. package/dist/chunk-7DTKRMYW.js.map +1 -0
  21. package/dist/{chunk-ONB2DAIV.js → chunk-D7H7SRWB.js} +455 -470
  22. package/dist/chunk-D7H7SRWB.js.map +1 -0
  23. package/dist/{chunk-BCQSE3EU.mjs → chunk-KUFWHMMY.mjs} +8 -8
  24. package/dist/{chunk-POKIJ56Q.mjs → chunk-KX7YG6LY.mjs} +22 -15
  25. package/dist/chunk-KX7YG6LY.mjs.map +1 -0
  26. package/dist/{chunk-GPGJNTHP.js → chunk-LI6CPNJI.js} +1 -1
  27. package/dist/{chunk-GPGJNTHP.js.map → chunk-LI6CPNJI.js.map} +1 -1
  28. package/dist/{chunk-5RAUCUAA.mjs → chunk-SXPXC2TY.mjs} +18 -33
  29. package/dist/chunk-SXPXC2TY.mjs.map +1 -0
  30. package/dist/{chunk-2AZLCF6D.js → chunk-UYY34W7R.js} +28 -28
  31. package/dist/{chunk-2AZLCF6D.js.map → chunk-UYY34W7R.js.map} +1 -1
  32. package/dist/chunk-VOXD3ZLY.mjs +26 -0
  33. package/dist/chunk-VOXD3ZLY.mjs.map +1 -0
  34. package/dist/client/index.d.mts +11 -45
  35. package/dist/client/index.d.ts +11 -45
  36. package/dist/client/index.js +9 -7
  37. package/dist/client/index.js.map +1 -1
  38. package/dist/client/index.mjs +11 -9
  39. package/dist/components/index.d.mts +4 -3
  40. package/dist/components/index.d.ts +4 -3
  41. package/dist/components/index.js +7 -6
  42. package/dist/components/index.js.map +1 -1
  43. package/dist/components/index.mjs +6 -5
  44. package/dist/{config-DEaUbBqR.d.ts → config--nwiW74Z.d.ts} +1 -1
  45. package/dist/{config-CWsTwnsK.d.mts → config-BKSQmUWU.d.mts} +1 -1
  46. package/dist/{content.interface-D_4b4RQt.d.ts → content.interface-4VICFRA0.d.ts} +2 -1
  47. package/dist/{content.interface-Dk4UZcJM.d.mts → content.interface-CFc97-Cj.d.mts} +2 -1
  48. package/dist/contexts/index.d.mts +3 -2
  49. package/dist/contexts/index.d.ts +3 -2
  50. package/dist/contexts/index.js +7 -6
  51. package/dist/contexts/index.js.map +1 -1
  52. package/dist/contexts/index.mjs +6 -5
  53. package/dist/core/index.d.mts +11 -8
  54. package/dist/core/index.d.ts +11 -8
  55. package/dist/core/index.js +4 -4
  56. package/dist/core/index.js.map +1 -1
  57. package/dist/core/index.mjs +3 -3
  58. package/dist/index.d.mts +15 -11
  59. package/dist/index.d.ts +15 -11
  60. package/dist/index.js +5 -5
  61. package/dist/index.js.map +1 -1
  62. package/dist/index.mjs +6 -6
  63. package/dist/{notification.interface-BllkURRm.d.ts → notification.interface-BGaPiCUM.d.mts} +2 -40
  64. package/dist/{notification.interface-BllkURRm.d.mts → notification.interface-CqwaOIgM.d.ts} +2 -40
  65. package/dist/{s3.service-BEfGqho0.d.ts → s3.service-BYs88XEE.d.ts} +3 -2
  66. package/dist/{s3.service-DIQRYe93.d.mts → s3.service-C0BjOdvn.d.mts} +3 -2
  67. package/dist/server/index.d.mts +6 -4
  68. package/dist/server/index.d.ts +6 -4
  69. package/dist/server/index.js +13 -13
  70. package/dist/server/index.js.map +1 -1
  71. package/dist/server/index.mjs +3 -3
  72. package/dist/{stripe-subscription.interface-C63L6hVg.d.mts → stripe-subscription.interface-B-TM40Io.d.ts} +1 -1
  73. package/dist/{stripe-subscription.interface-CUvNDvw5.d.ts → stripe-subscription.interface-DDxnpj0F.d.mts} +1 -1
  74. package/dist/testing/index.d.mts +338 -0
  75. package/dist/testing/index.d.ts +338 -0
  76. package/dist/testing/index.js +323 -0
  77. package/dist/testing/index.js.map +1 -0
  78. package/dist/testing/index.mjs +323 -0
  79. package/dist/testing/index.mjs.map +1 -0
  80. package/dist/{useSocket-BpenBR2z.d.mts → useSocket-BNj9PrRw.d.mts} +1 -1
  81. package/dist/{useSocket-D-QYA0Sr.d.ts → useSocket-Dwt8cz1x.d.ts} +1 -1
  82. package/package.json +21 -3
  83. package/src/client/hooks/__tests__/useJsonApiGet.test.tsx +229 -0
  84. package/src/client/hooks/__tests__/useJsonApiMutation.test.tsx +348 -0
  85. package/src/client/hooks/__tests__/useRehydration.test.ts +188 -0
  86. package/src/components/forms/__tests__/FormCheckbox.test.tsx +238 -0
  87. package/src/components/forms/__tests__/FormDate.test.tsx +212 -0
  88. package/src/components/forms/__tests__/FormInput.test.tsx +292 -0
  89. package/src/components/forms/__tests__/FormSelect.test.tsx +173 -0
  90. package/src/components/tables/__tests__/ContentListTable.test.tsx +411 -0
  91. package/src/core/endpoint/__tests__/EndpointCreator.test.ts +168 -0
  92. package/src/core/factories/__tests__/JsonApiDataFactory.test.ts +109 -0
  93. package/src/core/factories/__tests__/RehydrationFactory.test.ts +151 -0
  94. package/src/core/registry/__tests__/DataClassRegistry.test.ts +136 -0
  95. package/src/core/registry/__tests__/ModuleRegistrar.test.ts +159 -0
  96. package/src/features/auth/components/details/LandingComponent.tsx +14 -12
  97. package/src/hooks/__tests__/useDataListRetriever.test.ts +321 -0
  98. package/src/hooks/__tests__/useDebounce.test.ts +170 -0
  99. package/src/index.ts +4 -1
  100. package/src/login/config.ts +27 -0
  101. package/src/login/index.ts +2 -0
  102. package/src/testing/factories/createMockApiData.ts +143 -0
  103. package/src/testing/factories/createMockModule.ts +32 -0
  104. package/src/testing/factories/createMockResponse.ts +93 -0
  105. package/src/testing/factories/createMockService.ts +79 -0
  106. package/src/testing/index.ts +70 -0
  107. package/src/testing/matchers/jsonApiMatchers.ts +174 -0
  108. package/src/testing/providers/MockJsonApiProvider.tsx +58 -0
  109. package/src/testing/utils/renderWithProviders.tsx +76 -0
  110. package/src/utils/__tests__/date-formatter.test.ts +161 -0
  111. package/src/utils/__tests__/exists.test.ts +100 -0
  112. package/src/utils/cn.test.ts +44 -0
  113. package/dist/BlockNoteEditor-MBFDWP7X.js.map +0 -1
  114. package/dist/JsonApiRequest-45CLE65I.js +0 -24
  115. package/dist/chunk-5RAUCUAA.mjs.map +0 -1
  116. package/dist/chunk-ONB2DAIV.js.map +0 -1
  117. package/dist/chunk-POKIJ56Q.mjs.map +0 -1
  118. package/dist/chunk-R5QSSISB.js.map +0 -1
  119. package/src/discord/config.ts +0 -15
  120. package/src/discord/index.ts +0 -1
  121. /package/dist/{JsonApiRequest-6IPS3DZJ.mjs.map → JsonApiRequest-XWQWTFEQ.mjs.map} +0 -0
  122. /package/dist/{chunk-BCKYJQ3K.mjs.map → chunk-3VM3WAOV.mjs.map} +0 -0
  123. /package/dist/{chunk-BCQSE3EU.mjs.map → chunk-KUFWHMMY.mjs.map} +0 -0
@@ -0,0 +1,338 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React__default, { ReactElement } from 'react';
3
+ import { J as JsonApiConfig } from '../JsonApiContext-Bsm_Q2oe.js';
4
+ import { a as ApiRequestDataTypeInterface, A as ApiDataInterface } from '../ApiRequestDataTypeInterface-DIEOFn9s.js';
5
+ import { A as ApiResponseInterface } from '../ApiResponseInterface-BKyod24U.js';
6
+ import { Mock } from 'vitest';
7
+ import { RenderOptions, RenderResult } from '@testing-library/react';
8
+ export { fireEvent, render, screen, waitFor, within } from '@testing-library/react';
9
+ export { userEvent } from '@testing-library/user-event';
10
+
11
+ interface MockJsonApiProviderProps {
12
+ children: React__default.ReactNode;
13
+ config?: Partial<JsonApiConfig>;
14
+ }
15
+ declare const defaultMockConfig: JsonApiConfig;
16
+ /**
17
+ * A test-friendly provider that wraps components with mock JSON:API context.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * import { MockJsonApiProvider } from '@carlonicora/nextjs-jsonapi/testing';
22
+ *
23
+ * render(
24
+ * <MockJsonApiProvider>
25
+ * <MyComponent />
26
+ * </MockJsonApiProvider>
27
+ * );
28
+ * ```
29
+ *
30
+ * @example With custom config
31
+ * ```tsx
32
+ * render(
33
+ * <MockJsonApiProvider config={{ apiUrl: 'https://custom.api.com' }}>
34
+ * <MyComponent />
35
+ * </MockJsonApiProvider>
36
+ * );
37
+ * ```
38
+ */
39
+ declare function MockJsonApiProvider({ children, config }: MockJsonApiProviderProps): react_jsx_runtime.JSX.Element;
40
+
41
+ interface CreateMockModuleOptions {
42
+ name: string;
43
+ cache?: string;
44
+ inclusions?: ApiRequestDataTypeInterface["inclusions"];
45
+ }
46
+ /**
47
+ * Creates a mock module definition for testing.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * import { createMockModule } from '@carlonicora/nextjs-jsonapi/testing';
52
+ *
53
+ * const mockArticleModule = createMockModule({ name: 'articles' });
54
+ * ```
55
+ */
56
+ declare function createMockModule(options: CreateMockModuleOptions): ApiRequestDataTypeInterface;
57
+
58
+ interface CreateMockResponseOptions {
59
+ data?: ApiDataInterface | ApiDataInterface[] | null;
60
+ ok?: boolean;
61
+ response?: number;
62
+ error?: string;
63
+ meta?: Record<string, any>;
64
+ self?: string;
65
+ next?: string;
66
+ prev?: string;
67
+ }
68
+ /**
69
+ * Creates a mock API response for testing.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * import { createMockResponse, createMockApiData } from '@carlonicora/nextjs-jsonapi/testing';
74
+ *
75
+ * const mockData = createMockApiData({ type: 'articles', id: '1' });
76
+ * const response = createMockResponse({ data: mockData, ok: true });
77
+ * ```
78
+ *
79
+ * @example With pagination
80
+ * ```ts
81
+ * const response = createMockResponse({
82
+ * data: [mockData],
83
+ * ok: true,
84
+ * next: '/articles?page=2',
85
+ * prev: '/articles?page=0',
86
+ * });
87
+ * ```
88
+ */
89
+ declare function createMockResponse(options?: CreateMockResponseOptions): ApiResponseInterface;
90
+ /**
91
+ * Creates a mock error response for testing error scenarios.
92
+ *
93
+ * @example
94
+ * ```ts
95
+ * import { createMockErrorResponse } from '@carlonicora/nextjs-jsonapi/testing';
96
+ *
97
+ * const errorResponse = createMockErrorResponse(404, 'Not Found');
98
+ * ```
99
+ */
100
+ declare function createMockErrorResponse(statusCode: number, errorMessage: string): ApiResponseInterface;
101
+
102
+ type MockApiMethod = Mock<(...args: any[]) => Promise<ApiResponseInterface>>;
103
+ interface MockService {
104
+ get: MockApiMethod;
105
+ post: MockApiMethod;
106
+ put: MockApiMethod;
107
+ patch: MockApiMethod;
108
+ delete: MockApiMethod;
109
+ }
110
+ interface CreateMockServiceOptions {
111
+ defaultResponse?: ApiResponseInterface;
112
+ }
113
+ /**
114
+ * Creates a mock service with Vitest mock functions for all HTTP methods.
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * import { createMockService, createMockResponse } from '@carlonicora/nextjs-jsonapi/testing';
119
+ *
120
+ * const mockService = createMockService();
121
+ * mockService.get.mockResolvedValue(createMockResponse({ data: mockData }));
122
+ *
123
+ * // Use in test
124
+ * expect(mockService.get).toHaveBeenCalled();
125
+ * ```
126
+ *
127
+ * @example With default response
128
+ * ```ts
129
+ * const mockService = createMockService({
130
+ * defaultResponse: createMockResponse({ ok: true, data: [] }),
131
+ * });
132
+ * ```
133
+ */
134
+ declare function createMockService(options?: CreateMockServiceOptions): MockService;
135
+ /**
136
+ * Creates a mock service that returns errors for all methods.
137
+ *
138
+ * @example
139
+ * ```ts
140
+ * import { createMockErrorService } from '@carlonicora/nextjs-jsonapi/testing';
141
+ *
142
+ * const errorService = createMockErrorService(500, 'Internal Server Error');
143
+ * ```
144
+ */
145
+ declare function createMockErrorService(statusCode?: number, errorMessage?: string): MockService;
146
+
147
+ interface CreateMockApiDataOptions {
148
+ type: string;
149
+ id?: string;
150
+ attributes?: Record<string, any>;
151
+ relationships?: Record<string, any>;
152
+ included?: any[];
153
+ createdAt?: Date;
154
+ updatedAt?: Date;
155
+ self?: string;
156
+ }
157
+ /**
158
+ * Creates a mock ApiDataInterface object for testing.
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * import { createMockApiData } from '@carlonicora/nextjs-jsonapi/testing';
163
+ *
164
+ * const mockArticle = createMockApiData({
165
+ * type: 'articles',
166
+ * id: '1',
167
+ * attributes: { title: 'Test Article', body: 'Content here' },
168
+ * });
169
+ * ```
170
+ *
171
+ * @example With relationships
172
+ * ```ts
173
+ * const mockArticle = createMockApiData({
174
+ * type: 'articles',
175
+ * id: '1',
176
+ * attributes: { title: 'Test' },
177
+ * relationships: {
178
+ * author: { data: { type: 'users', id: '42' } },
179
+ * },
180
+ * });
181
+ * ```
182
+ */
183
+ declare function createMockApiData(options: CreateMockApiDataOptions): ApiDataInterface;
184
+ /**
185
+ * Creates an array of mock ApiDataInterface objects.
186
+ *
187
+ * @example
188
+ * ```ts
189
+ * import { createMockApiDataList } from '@carlonicora/nextjs-jsonapi/testing';
190
+ *
191
+ * const mockArticles = createMockApiDataList('articles', 5, (index) => ({
192
+ * title: `Article ${index + 1}`,
193
+ * }));
194
+ * ```
195
+ */
196
+ declare function createMockApiDataList(type: string, count: number, attributesFactory?: (index: number) => Record<string, any>): ApiDataInterface[];
197
+
198
+ interface JsonApiResponse {
199
+ data?: {
200
+ type?: string;
201
+ id?: string;
202
+ attributes?: Record<string, any>;
203
+ relationships?: Record<string, any>;
204
+ } | Array<{
205
+ type?: string;
206
+ id?: string;
207
+ attributes?: Record<string, any>;
208
+ relationships?: Record<string, any>;
209
+ }>;
210
+ }
211
+ /**
212
+ * Custom Vitest matchers for JSON:API assertions.
213
+ *
214
+ * @example
215
+ * ```ts
216
+ * import { jsonApiMatchers } from '@carlonicora/nextjs-jsonapi/testing';
217
+ * import { expect } from 'vitest';
218
+ *
219
+ * expect.extend(jsonApiMatchers);
220
+ *
221
+ * // Then use in tests:
222
+ * expect(response).toBeValidJsonApi();
223
+ * expect(response).toHaveJsonApiType('articles');
224
+ * expect(response).toHaveJsonApiAttribute('title', 'My Article');
225
+ * expect(response).toHaveJsonApiRelationship('author');
226
+ * ```
227
+ */
228
+ declare const jsonApiMatchers: {
229
+ /**
230
+ * Asserts that the response has a valid JSON:API structure with type and id.
231
+ */
232
+ toBeValidJsonApi(received: JsonApiResponse): {
233
+ pass: boolean;
234
+ message: () => string;
235
+ };
236
+ /**
237
+ * Asserts that the response data has the expected JSON:API type.
238
+ */
239
+ toHaveJsonApiType(received: JsonApiResponse, expectedType: string): {
240
+ pass: boolean;
241
+ message: () => string;
242
+ };
243
+ /**
244
+ * Asserts that the response data has an attribute with the expected value.
245
+ */
246
+ toHaveJsonApiAttribute(received: JsonApiResponse, attributeName: string, expectedValue?: any): {
247
+ pass: boolean;
248
+ message: () => string;
249
+ };
250
+ /**
251
+ * Asserts that the response data has the specified relationship.
252
+ */
253
+ toHaveJsonApiRelationship(received: JsonApiResponse, relationshipName: string): {
254
+ pass: boolean;
255
+ message: () => string;
256
+ };
257
+ /**
258
+ * Asserts that the response data array has the expected length.
259
+ */
260
+ toHaveJsonApiLength(received: JsonApiResponse, expectedLength: number): {
261
+ pass: boolean;
262
+ message: () => string;
263
+ };
264
+ };
265
+ declare module "vitest" {
266
+ interface Assertion<T = any> {
267
+ toBeValidJsonApi(): T;
268
+ toHaveJsonApiType(expectedType: string): T;
269
+ toHaveJsonApiAttribute(attributeName: string, expectedValue?: any): T;
270
+ toHaveJsonApiRelationship(relationshipName: string): T;
271
+ toHaveJsonApiLength(expectedLength: number): T;
272
+ }
273
+ interface AsymmetricMatchersContaining {
274
+ toBeValidJsonApi(): any;
275
+ toHaveJsonApiType(expectedType: string): any;
276
+ toHaveJsonApiAttribute(attributeName: string, expectedValue?: any): any;
277
+ toHaveJsonApiRelationship(relationshipName: string): any;
278
+ toHaveJsonApiLength(expectedLength: number): any;
279
+ }
280
+ }
281
+ /**
282
+ * Extends Vitest's expect with JSON:API matchers.
283
+ * Call this in your test setup file.
284
+ *
285
+ * @example
286
+ * ```ts
287
+ * // vitest.setup.ts
288
+ * import { extendExpectWithJsonApiMatchers } from '@carlonicora/nextjs-jsonapi/testing';
289
+ *
290
+ * extendExpectWithJsonApiMatchers();
291
+ * ```
292
+ */
293
+ declare function extendExpectWithJsonApiMatchers(): void;
294
+
295
+ interface RenderWithProvidersOptions extends Omit<RenderOptions, "wrapper"> {
296
+ /**
297
+ * Custom JSON:API configuration to pass to the mock provider.
298
+ */
299
+ jsonApiConfig?: Partial<JsonApiConfig>;
300
+ /**
301
+ * Additional wrapper component to wrap around the providers.
302
+ */
303
+ wrapper?: React__default.ComponentType<{
304
+ children: React__default.ReactNode;
305
+ }>;
306
+ }
307
+ /**
308
+ * Renders a component wrapped with all necessary providers for testing.
309
+ *
310
+ * @example
311
+ * ```tsx
312
+ * import { renderWithProviders } from '@carlonicora/nextjs-jsonapi/testing';
313
+ *
314
+ * const { getByText } = renderWithProviders(<MyComponent />);
315
+ * expect(getByText('Hello')).toBeInTheDocument();
316
+ * ```
317
+ *
318
+ * @example With custom config
319
+ * ```tsx
320
+ * const { getByText } = renderWithProviders(<MyComponent />, {
321
+ * jsonApiConfig: { apiUrl: 'https://custom.api.com' },
322
+ * });
323
+ * ```
324
+ *
325
+ * @example With additional wrapper
326
+ * ```tsx
327
+ * const CustomWrapper = ({ children }) => (
328
+ * <ThemeProvider>{children}</ThemeProvider>
329
+ * );
330
+ *
331
+ * const { getByText } = renderWithProviders(<MyComponent />, {
332
+ * wrapper: CustomWrapper,
333
+ * });
334
+ * ```
335
+ */
336
+ declare function renderWithProviders(ui: ReactElement, options?: RenderWithProvidersOptions): RenderResult;
337
+
338
+ export { type CreateMockApiDataOptions, type CreateMockModuleOptions, type CreateMockResponseOptions, type CreateMockServiceOptions, type MockApiMethod, MockJsonApiProvider, type MockJsonApiProviderProps, type MockService, type RenderWithProvidersOptions, createMockApiData, createMockApiDataList, createMockErrorResponse, createMockErrorService, createMockModule, createMockResponse, createMockService, defaultMockConfig, extendExpectWithJsonApiMatchers, jsonApiMatchers, renderWithProviders };
@@ -0,0 +1,323 @@
1
+ "use client";
2
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
3
+
4
+ var _chunk3EPNHTMHjs = require('../chunk-3EPNHTMH.js');
5
+
6
+
7
+ var _chunk7QVYU63Ejs = require('../chunk-7QVYU63E.js');
8
+
9
+ // src/testing/providers/MockJsonApiProvider.tsx
10
+ var _jsxruntime = require('react/jsx-runtime');
11
+ var defaultMockConfig = {
12
+ apiUrl: "https://api.test.com",
13
+ tokenGetter: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => "mock-token-for-testing", "tokenGetter"),
14
+ languageGetter: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => "en", "languageGetter"),
15
+ defaultHeaders: {},
16
+ onError: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => {
17
+ }, "onError"),
18
+ cacheConfig: {
19
+ defaultProfile: "default"
20
+ }
21
+ };
22
+ function MockJsonApiProvider({ children, config }) {
23
+ const mergedConfig = {
24
+ ...defaultMockConfig,
25
+ ...config
26
+ };
27
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3EPNHTMHjs.JsonApiContext.Provider, { value: mergedConfig, children });
28
+ }
29
+ _chunk7QVYU63Ejs.__name.call(void 0, MockJsonApiProvider, "MockJsonApiProvider");
30
+
31
+ // src/testing/factories/createMockModule.ts
32
+ function createMockModule(options) {
33
+ class MockModel {constructor() { MockModel.prototype.__init.call(this);MockModel.prototype.__init2.call(this); }
34
+ static {
35
+ _chunk7QVYU63Ejs.__name.call(void 0, this, "MockModel");
36
+ }
37
+ __init() {this.id = "mock-id"}
38
+ __init2() {this.type = options.name}
39
+ }
40
+ return {
41
+ name: options.name,
42
+ cache: options.cache,
43
+ inclusions: options.inclusions,
44
+ model: MockModel
45
+ };
46
+ }
47
+ _chunk7QVYU63Ejs.__name.call(void 0, createMockModule, "createMockModule");
48
+
49
+ // src/testing/factories/createMockResponse.ts
50
+ function createMockResponse(options = {}) {
51
+ const {
52
+ data = null,
53
+ ok = true,
54
+ response = ok ? 200 : 500,
55
+ error = ok ? "" : "Error",
56
+ meta,
57
+ self,
58
+ next,
59
+ prev
60
+ } = options;
61
+ const mockResponse = {
62
+ ok,
63
+ response,
64
+ data,
65
+ error,
66
+ meta,
67
+ self,
68
+ next,
69
+ prev
70
+ };
71
+ if (next) {
72
+ mockResponse.nextPage = async () => createMockResponse({ ...options, next: void 0, prev: self });
73
+ }
74
+ if (prev) {
75
+ mockResponse.prevPage = async () => createMockResponse({ ...options, prev: void 0, next: self });
76
+ }
77
+ return mockResponse;
78
+ }
79
+ _chunk7QVYU63Ejs.__name.call(void 0, createMockResponse, "createMockResponse");
80
+ function createMockErrorResponse(statusCode, errorMessage) {
81
+ return createMockResponse({
82
+ ok: false,
83
+ response: statusCode,
84
+ error: errorMessage,
85
+ data: null
86
+ });
87
+ }
88
+ _chunk7QVYU63Ejs.__name.call(void 0, createMockErrorResponse, "createMockErrorResponse");
89
+
90
+ // src/testing/factories/createMockService.ts
91
+ var _vitest = require('vitest');
92
+ function createMockService(options = {}) {
93
+ const defaultResponse = _nullishCoalesce(options.defaultResponse, () => ( createMockResponse({ ok: true })));
94
+ return {
95
+ get: _vitest.vi.fn().mockResolvedValue(defaultResponse),
96
+ post: _vitest.vi.fn().mockResolvedValue(defaultResponse),
97
+ put: _vitest.vi.fn().mockResolvedValue(defaultResponse),
98
+ patch: _vitest.vi.fn().mockResolvedValue(defaultResponse),
99
+ delete: _vitest.vi.fn().mockResolvedValue(defaultResponse)
100
+ };
101
+ }
102
+ _chunk7QVYU63Ejs.__name.call(void 0, createMockService, "createMockService");
103
+ function createMockErrorService(statusCode = 500, errorMessage = "Error") {
104
+ const errorResponse = createMockResponse({
105
+ ok: false,
106
+ response: statusCode,
107
+ error: errorMessage
108
+ });
109
+ return {
110
+ get: _vitest.vi.fn().mockResolvedValue(errorResponse),
111
+ post: _vitest.vi.fn().mockResolvedValue(errorResponse),
112
+ put: _vitest.vi.fn().mockResolvedValue(errorResponse),
113
+ patch: _vitest.vi.fn().mockResolvedValue(errorResponse),
114
+ delete: _vitest.vi.fn().mockResolvedValue(errorResponse)
115
+ };
116
+ }
117
+ _chunk7QVYU63Ejs.__name.call(void 0, createMockErrorService, "createMockErrorService");
118
+
119
+ // src/testing/factories/createMockApiData.ts
120
+ function createMockApiData(options) {
121
+ const {
122
+ type,
123
+ id = `mock-${type}-${Math.random().toString(36).substring(7)}`,
124
+ attributes = {},
125
+ relationships = {},
126
+ included = [],
127
+ createdAt = /* @__PURE__ */ new Date(),
128
+ updatedAt = /* @__PURE__ */ new Date(),
129
+ self
130
+ } = options;
131
+ const jsonApiData = {
132
+ type,
133
+ id,
134
+ attributes: {
135
+ ...attributes,
136
+ createdAt: createdAt.toISOString(),
137
+ updatedAt: updatedAt.toISOString()
138
+ },
139
+ relationships
140
+ };
141
+ const mockData = {
142
+ get included() {
143
+ return included;
144
+ },
145
+ get type() {
146
+ return type;
147
+ },
148
+ get id() {
149
+ return id;
150
+ },
151
+ get createdAt() {
152
+ return createdAt;
153
+ },
154
+ get updatedAt() {
155
+ return updatedAt;
156
+ },
157
+ get self() {
158
+ return self;
159
+ },
160
+ get jsonApi() {
161
+ return jsonApiData;
162
+ },
163
+ generateApiUrl: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (params) => {
164
+ const baseUrl = `/${type}/${id}`;
165
+ if (params) {
166
+ const searchParams = new URLSearchParams(params);
167
+ return `${baseUrl}?${searchParams.toString()}`;
168
+ }
169
+ return baseUrl;
170
+ }, "generateApiUrl"),
171
+ dehydrate: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => ({
172
+ jsonApi: jsonApiData,
173
+ included,
174
+ allData: [jsonApiData]
175
+ }), "dehydrate"),
176
+ rehydrate: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, function(data) {
177
+ return this;
178
+ }, "rehydrate"),
179
+ createJsonApi: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (data) => ({
180
+ type,
181
+ id,
182
+ attributes: data
183
+ }), "createJsonApi")
184
+ };
185
+ Object.keys(attributes).forEach((key) => {
186
+ Object.defineProperty(mockData, key, {
187
+ get: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => attributes[key], "get"),
188
+ enumerable: true
189
+ });
190
+ });
191
+ return mockData;
192
+ }
193
+ _chunk7QVYU63Ejs.__name.call(void 0, createMockApiData, "createMockApiData");
194
+ function createMockApiDataList(type, count, attributesFactory) {
195
+ return Array.from(
196
+ { length: count },
197
+ (_, index) => createMockApiData({
198
+ type,
199
+ id: `${index + 1}`,
200
+ attributes: _nullishCoalesce(_optionalChain([attributesFactory, 'optionalCall', _2 => _2(index)]), () => ( {}))
201
+ })
202
+ );
203
+ }
204
+ _chunk7QVYU63Ejs.__name.call(void 0, createMockApiDataList, "createMockApiDataList");
205
+
206
+ // src/testing/matchers/jsonApiMatchers.ts
207
+
208
+ var jsonApiMatchers = {
209
+ /**
210
+ * Asserts that the response has a valid JSON:API structure with type and id.
211
+ */
212
+ toBeValidJsonApi(received) {
213
+ const data = Array.isArray(_optionalChain([received, 'optionalAccess', _3 => _3.data])) ? received.data[0] : _optionalChain([received, 'optionalAccess', _4 => _4.data]);
214
+ const hasType = typeof _optionalChain([data, 'optionalAccess', _5 => _5.type]) === "string" && data.type.length > 0;
215
+ const hasId = typeof _optionalChain([data, 'optionalAccess', _6 => _6.id]) === "string" && data.id.length > 0;
216
+ const isValid = hasType && hasId;
217
+ return {
218
+ pass: isValid,
219
+ message: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => isValid ? `Expected response not to be valid JSON:API, but it has type "${_optionalChain([data, 'optionalAccess', _7 => _7.type])}" and id "${_optionalChain([data, 'optionalAccess', _8 => _8.id])}"` : `Expected response to be valid JSON:API with type and id, but got type: ${JSON.stringify(_optionalChain([data, 'optionalAccess', _9 => _9.type]))}, id: ${JSON.stringify(_optionalChain([data, 'optionalAccess', _10 => _10.id]))}`, "message")
220
+ };
221
+ },
222
+ /**
223
+ * Asserts that the response data has the expected JSON:API type.
224
+ */
225
+ toHaveJsonApiType(received, expectedType) {
226
+ const data = Array.isArray(_optionalChain([received, 'optionalAccess', _11 => _11.data])) ? received.data[0] : _optionalChain([received, 'optionalAccess', _12 => _12.data]);
227
+ const actualType = _optionalChain([data, 'optionalAccess', _13 => _13.type]);
228
+ const pass = actualType === expectedType;
229
+ return {
230
+ pass,
231
+ message: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => pass ? `Expected response not to have JSON:API type "${expectedType}"` : `Expected response to have JSON:API type "${expectedType}", but got "${actualType}"`, "message")
232
+ };
233
+ },
234
+ /**
235
+ * Asserts that the response data has an attribute with the expected value.
236
+ */
237
+ toHaveJsonApiAttribute(received, attributeName, expectedValue) {
238
+ const data = Array.isArray(_optionalChain([received, 'optionalAccess', _14 => _14.data])) ? received.data[0] : _optionalChain([received, 'optionalAccess', _15 => _15.data]);
239
+ const attributes = _nullishCoalesce(_optionalChain([data, 'optionalAccess', _16 => _16.attributes]), () => ( {}));
240
+ const hasAttribute = attributeName in attributes;
241
+ const actualValue = attributes[attributeName];
242
+ if (expectedValue === void 0) {
243
+ return {
244
+ pass: hasAttribute,
245
+ message: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => hasAttribute ? `Expected response not to have JSON:API attribute "${attributeName}"` : `Expected response to have JSON:API attribute "${attributeName}", but it was not found. Available attributes: ${Object.keys(attributes).join(", ") || "none"}`, "message")
246
+ };
247
+ }
248
+ const valuesMatch = actualValue === expectedValue;
249
+ return {
250
+ pass: hasAttribute && valuesMatch,
251
+ message: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => hasAttribute && valuesMatch ? `Expected response not to have JSON:API attribute "${attributeName}" with value "${expectedValue}"` : !hasAttribute ? `Expected response to have JSON:API attribute "${attributeName}", but it was not found` : `Expected JSON:API attribute "${attributeName}" to be "${expectedValue}", but got "${actualValue}"`, "message")
252
+ };
253
+ },
254
+ /**
255
+ * Asserts that the response data has the specified relationship.
256
+ */
257
+ toHaveJsonApiRelationship(received, relationshipName) {
258
+ const data = Array.isArray(_optionalChain([received, 'optionalAccess', _17 => _17.data])) ? received.data[0] : _optionalChain([received, 'optionalAccess', _18 => _18.data]);
259
+ const relationships = _nullishCoalesce(_optionalChain([data, 'optionalAccess', _19 => _19.relationships]), () => ( {}));
260
+ const hasRelationship = relationshipName in relationships;
261
+ return {
262
+ pass: hasRelationship,
263
+ message: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => hasRelationship ? `Expected response not to have JSON:API relationship "${relationshipName}"` : `Expected response to have JSON:API relationship "${relationshipName}", but it was not found. Available relationships: ${Object.keys(relationships).join(", ") || "none"}`, "message")
264
+ };
265
+ },
266
+ /**
267
+ * Asserts that the response data array has the expected length.
268
+ */
269
+ toHaveJsonApiLength(received, expectedLength) {
270
+ const data = _optionalChain([received, 'optionalAccess', _20 => _20.data]);
271
+ const isArray = Array.isArray(data);
272
+ const actualLength = isArray ? data.length : data ? 1 : 0;
273
+ const pass = actualLength === expectedLength;
274
+ return {
275
+ pass,
276
+ message: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => pass ? `Expected response not to have ${expectedLength} items` : `Expected response to have ${expectedLength} items, but got ${actualLength}`, "message")
277
+ };
278
+ }
279
+ };
280
+ function extendExpectWithJsonApiMatchers() {
281
+ _vitest.expect.extend(jsonApiMatchers);
282
+ }
283
+ _chunk7QVYU63Ejs.__name.call(void 0, extendExpectWithJsonApiMatchers, "extendExpectWithJsonApiMatchers");
284
+
285
+ // src/testing/utils/renderWithProviders.tsx
286
+ var _react = require('@testing-library/react');
287
+
288
+ var _userevent = require('@testing-library/user-event');
289
+
290
+ function renderWithProviders(ui, options = {}) {
291
+ const { jsonApiConfig, wrapper: AdditionalWrapper, ...renderOptions } = options;
292
+ function AllProviders({ children }) {
293
+ const content = /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MockJsonApiProvider, { config: jsonApiConfig, children });
294
+ if (AdditionalWrapper) {
295
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AdditionalWrapper, { children: content });
296
+ }
297
+ return content;
298
+ }
299
+ _chunk7QVYU63Ejs.__name.call(void 0, AllProviders, "AllProviders");
300
+ return _react.render.call(void 0, ui, { wrapper: AllProviders, ...renderOptions });
301
+ }
302
+ _chunk7QVYU63Ejs.__name.call(void 0, renderWithProviders, "renderWithProviders");
303
+
304
+
305
+
306
+
307
+
308
+
309
+
310
+
311
+
312
+
313
+
314
+
315
+
316
+
317
+
318
+
319
+
320
+
321
+
322
+ exports.MockJsonApiProvider = MockJsonApiProvider; exports.createMockApiData = createMockApiData; exports.createMockApiDataList = createMockApiDataList; exports.createMockErrorResponse = createMockErrorResponse; exports.createMockErrorService = createMockErrorService; exports.createMockModule = createMockModule; exports.createMockResponse = createMockResponse; exports.createMockService = createMockService; exports.defaultMockConfig = defaultMockConfig; exports.extendExpectWithJsonApiMatchers = extendExpectWithJsonApiMatchers; exports.fireEvent = _react.fireEvent; exports.jsonApiMatchers = jsonApiMatchers; exports.render = _react.render; exports.renderWithProviders = renderWithProviders; exports.screen = _react.screen; exports.userEvent = _userevent.userEvent; exports.waitFor = _react.waitFor; exports.within = _react.within;
323
+ //# sourceMappingURL=index.js.map