@classytic/arc-next 0.2.0 → 0.3.1
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.
- package/README.md +25 -20
- package/dist/api.d.ts +1 -2
- package/dist/api.js +11 -4
- package/dist/client.d.ts +18 -2
- package/dist/client.js +11 -5
- package/dist/hooks.d.ts +15 -58
- package/dist/hooks.js +90 -85
- package/dist/mutation.d.ts +6 -3
- package/dist/mutation.js +6 -3
- package/dist/prefetch.d.ts +9 -3
- package/dist/prefetch.js +9 -5
- package/dist/query-client.d.ts +1 -2
- package/dist/query-client.js +2 -2
- package/dist/query.d.ts +18 -5
- package/dist/query.js +54 -19
- package/package.json +9 -3
- package/dist/api.d.ts.map +0 -1
- package/dist/api.js.map +0 -1
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js.map +0 -1
- package/dist/hooks.d.ts.map +0 -1
- package/dist/hooks.js.map +0 -1
- package/dist/mutation.d.ts.map +0 -1
- package/dist/mutation.js.map +0 -1
- package/dist/prefetch.d.ts.map +0 -1
- package/dist/prefetch.js.map +0 -1
- package/dist/query-client.d.ts.map +0 -1
- package/dist/query-client.js.map +0 -1
- package/dist/query.d.ts.map +0 -1
- package/dist/query.js.map +0 -1
package/README.md
CHANGED
|
@@ -30,13 +30,13 @@ import { useRouter } from "next/navigation";
|
|
|
30
30
|
// Required — sets the API base URL and auth mode
|
|
31
31
|
configureClient({
|
|
32
32
|
baseUrl: process.env.NEXT_PUBLIC_API_URL!,
|
|
33
|
-
authMode: "cookie",
|
|
34
|
-
|
|
33
|
+
authMode: "cookie", // 'cookie' for Better Auth, 'bearer' for token auth (default)
|
|
34
|
+
// credentials: 'omit', // override if you don't want cookies sent cross-origin
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
// Optional — auto-inject
|
|
37
|
+
// Optional — auto-inject tenant context into queries/mutations
|
|
38
38
|
configureAuth({
|
|
39
|
-
getOrgId: () =>
|
|
39
|
+
getOrgId: () => activeTenantId, // return current tenant/org/workspace ID
|
|
40
40
|
getToken: () => null, // null for cookie auth (token only for bearer)
|
|
41
41
|
});
|
|
42
42
|
|
|
@@ -51,10 +51,11 @@ configureNavigation(useRouter);
|
|
|
51
51
|
|
|
52
52
|
| Import | Purpose | `"use client"` |
|
|
53
53
|
| ----------------------------------- | ---------------------------------------------------------------------------- | :-------------: |
|
|
54
|
+
| `@classytic/arc-next` | Root — same as `/hooks` (`createCrudHooks`, `configureNavigation`) | Yes |
|
|
54
55
|
| `@classytic/arc-next/client` | `configureClient`, `configureAuth`, `createClient`, `handleApiRequest`, `createQueryString`, `ArcApiError`, `isArcApiError`, `getAuthMode`, `getAuthContext` | No |
|
|
55
56
|
| `@classytic/arc-next/api` | `BaseApi`, `createCrudApi`, response types, type guards | No |
|
|
56
|
-
| `@classytic/arc-next/query` | `createQueryKeys`, `createCacheUtils`, `
|
|
57
|
-
| `@classytic/arc-next/mutation` | `configureToast`, `useMutationWithTransition`, `
|
|
57
|
+
| `@classytic/arc-next/query` | `createQueryKeys`, `createCacheUtils`, `useListQuery`, `useDetailQuery` | Yes |
|
|
58
|
+
| `@classytic/arc-next/mutation` | `configureToast`, `useMutationWithTransition`, `useOptimisticMutation` | Yes |
|
|
58
59
|
| `@classytic/arc-next/hooks` | `createCrudHooks`, `configureNavigation` | Yes |
|
|
59
60
|
| `@classytic/arc-next/query-client` | `getQueryClient` (SSR-safe singleton) | No |
|
|
60
61
|
| `@classytic/arc-next/prefetch` | `createCrudPrefetcher`, `dehydrate` (SSR prefetch) | No |
|
|
@@ -148,13 +149,15 @@ export function ProductsPage() {
|
|
|
148
149
|
configureClient({
|
|
149
150
|
baseUrl: string; // Required — API base URL
|
|
150
151
|
authMode?: 'cookie' | 'bearer'; // Default: 'bearer'
|
|
152
|
+
credentials?: RequestCredentials; // Default: derived from authMode
|
|
151
153
|
internalApiKey?: string; // Optional — sent as x-internal-api-key header
|
|
152
154
|
defaultHeaders?: Record<string, string>; // Optional — merged into every request
|
|
153
155
|
});
|
|
154
156
|
```
|
|
155
157
|
|
|
156
|
-
- `authMode: 'bearer'` (default) — requires a token
|
|
157
|
-
- `authMode: 'cookie'` —
|
|
158
|
+
- `authMode: 'bearer'` (default) — requires a token; queries disabled until token provided; `credentials: 'same-origin'`
|
|
159
|
+
- `authMode: 'cookie'` — HTTP-only cookies (e.g. Better Auth); queries always enabled; `credentials: 'include'`
|
|
160
|
+
- `credentials` — explicit override: `'include'` (send cookies cross-origin), `'same-origin'` (same-origin only), `'omit'` (never send cookies)
|
|
158
161
|
|
|
159
162
|
Must be called before any API requests. Throws if not configured.
|
|
160
163
|
|
|
@@ -167,7 +170,7 @@ configureAuth({
|
|
|
167
170
|
});
|
|
168
171
|
```
|
|
169
172
|
|
|
170
|
-
Auto-injects `token` and `
|
|
173
|
+
Auto-injects `token` and tenant ID (sent as `x-organization-id` header) into queries/mutations. The header name is a convention — your backend controls how it's read and which field it maps to (`organizationId`, `workspaceId`, `teamId`, etc.). Hooks use the new signature (no explicit token param) — legacy signature still works.
|
|
171
174
|
|
|
172
175
|
### `handleApiRequest<T>(method, endpoint, options?)`
|
|
173
176
|
|
|
@@ -226,7 +229,7 @@ const api = createCrudApi<Product, CreateProduct>("products", {
|
|
|
226
229
|
|
|
227
230
|
### `createCrudHooks<T, TCreate, TUpdate>(config)`
|
|
228
231
|
|
|
229
|
-
Factory that returns everything you need:
|
|
232
|
+
Factory that returns everything you need. The `api` parameter accepts any `createCrudApi()` result directly — no casts needed. Types are derived from `BaseApi` via `Pick`, so generics thread through automatically:
|
|
230
233
|
|
|
231
234
|
```ts
|
|
232
235
|
const {
|
|
@@ -235,7 +238,7 @@ const {
|
|
|
235
238
|
useActions, useUpload, useSearch, useCustomMutation,
|
|
236
239
|
useNavigation,
|
|
237
240
|
} = createCrudHooks<Product, CreateProduct>({
|
|
238
|
-
api: productsApi, // from createCrudApi()
|
|
241
|
+
api: productsApi, // from createCrudApi() — types inferred, no cast
|
|
239
242
|
entityKey: "products", // TanStack Query key prefix
|
|
240
243
|
singular: "Product", // for toast messages
|
|
241
244
|
defaults: { // optional
|
|
@@ -263,7 +266,7 @@ const { items, pagination, isLoading, isFetching, refetch } = useList(
|
|
|
263
266
|
);
|
|
264
267
|
```
|
|
265
268
|
|
|
266
|
-
- Auto-scopes query keys by
|
|
269
|
+
- Auto-scopes list query keys by tenant context (when present → `tenant` scope, otherwise → `super-admin`)
|
|
267
270
|
- Normalizes pagination from `docs`/`data`/`items`/`results` formats
|
|
268
271
|
- Prefills detail cache from list results (skips re-fetch on navigate)
|
|
269
272
|
- `options.public: true` — enables query without token
|
|
@@ -534,7 +537,7 @@ useProducts(token, {}, { ...QUERY_CONFIGS.realtime });
|
|
|
534
537
|
|
|
535
538
|
### `updateListCache(listData, updater)`
|
|
536
539
|
|
|
537
|
-
Transforms list cache regardless of format (`docs[]`, `data[]`, `items[]`, `results[]`, or raw
|
|
540
|
+
Transforms list cache regardless of format — well-known keys (`docs[]`, `data[]`, `items[]`, `results[]`), custom keys (`products[]`, `users[]`, etc.), or raw arrays.
|
|
538
541
|
Automatically adjusts `total`/`totalDocs` counts when items are added or removed (optimistic add/delete).
|
|
539
542
|
|
|
540
543
|
```ts
|
|
@@ -551,11 +554,11 @@ Extracts `_id` or `id` from any item. Returns `string | null`.
|
|
|
551
554
|
|
|
552
555
|
### `normalizePagination(data)`
|
|
553
556
|
|
|
554
|
-
Converts any pagination response format to a normalized `PaginationData` object.
|
|
557
|
+
Converts any pagination response format to a normalized `PaginationData` object. Detects pagination method (`offset`, `keyset`, `aggregate`) and normalizes all fields: `total`/`totalDocs`, `pages`/`totalPages`, `page`/`currentPage`, `hasNext`/`hasNextPage`/`hasMore`, `hasPrev`/`hasPrevPage`, `next` (keyset cursor).
|
|
555
558
|
|
|
556
559
|
### `extractItems<T>(data)`
|
|
557
560
|
|
|
558
|
-
Extracts the items array from any response format
|
|
561
|
+
Extracts the items array from any response format. Checks well-known keys first (`docs`, `data`, `items`, `results`), then falls back to finding the first top-level array — so `{ products: [...] }` or `{ users: [...] }` works without configuration.
|
|
559
562
|
|
|
560
563
|
## Multi-Client (Multiple APIs)
|
|
561
564
|
|
|
@@ -654,8 +657,10 @@ try {
|
|
|
654
657
|
### Multi-tenant data fetching
|
|
655
658
|
|
|
656
659
|
```ts
|
|
657
|
-
//
|
|
658
|
-
|
|
660
|
+
// Tenant ID in params → scoped query key → isolated cache per tenant
|
|
661
|
+
// The param name is up to you — arc-next sends it as x-organization-id header,
|
|
662
|
+
// your backend maps it to whatever tenant field your schema uses.
|
|
663
|
+
const { items } = useProducts(token, { organizationId: currentTenantId });
|
|
659
664
|
```
|
|
660
665
|
|
|
661
666
|
### Public endpoints (no auth)
|
|
@@ -704,11 +709,11 @@ const adminApi = createCrudApi("users", {
|
|
|
704
709
|
|
|
705
710
|
- **CRUD Factory** — `createCrudApi` + `createCrudHooks` generates typed API clients and React Query hooks
|
|
706
711
|
- **Optimistic Updates** — Create, update, delete with instant UI feedback and automatic rollback
|
|
707
|
-
- **Multi-Tenant Scoping** — `
|
|
708
|
-
- **Pagination Normalization** — Handles `docs`/`data`/`items`/`results`
|
|
712
|
+
- **Multi-Tenant Scoping** — Tenant ID sent via `x-organization-id` header + scoped list query keys. Backend controls the tenant field name and access enforcement.
|
|
713
|
+
- **Pagination Normalization** — Handles `docs`/`data`/`items`/`results` + any custom key, offset/keyset/aggregate pagination
|
|
709
714
|
- **Detail Cache Prefilling** — List results auto-populate detail query cache
|
|
710
715
|
- **React 19 Transitions** — `useMutationWithTransition` wraps invalidation in `startTransition`
|
|
711
|
-
- **Cookie & Bearer Auth** — `authMode: 'cookie'` for Better Auth, `'bearer'` for token auth
|
|
716
|
+
- **Cookie & Bearer Auth** — `authMode: 'cookie'` for Better Auth, `'bearer'` for token auth, configurable `credentials` policy
|
|
712
717
|
- **SSR Prefetch** — `createCrudPrefetcher` + `dehydrate` for server component data loading
|
|
713
718
|
- **Multi-Client** — `createClient()` for multiple API backends side by side
|
|
714
719
|
- **Pluggable Toast** — `configureToast()` — use sonner, react-hot-toast, or anything
|
package/dist/api.d.ts
CHANGED
|
@@ -225,5 +225,4 @@ declare function isOffsetPagination<T>(response: PaginatedResponse<T>): response
|
|
|
225
225
|
declare function isKeysetPagination<T>(response: PaginatedResponse<T>): response is KeysetPaginationResponse<T>;
|
|
226
226
|
declare function isAggregatePagination<T>(response: PaginatedResponse<T>): response is AggregatePaginationResponse<T>;
|
|
227
227
|
//#endregion
|
|
228
|
-
export { AggregatePaginationResponse, ApiResponse, BaseApi, BaseApiConfig, DeleteResponse, ExtractDoc, FilterOperator, KeysetPaginationResponse, OffsetPaginationResponse, PaginatedResponse, PopulateOption, QueryParams, RequestOptions, SortDirection, SortSpec, createCrudApi, isAggregatePagination, isKeysetPagination, isOffsetPagination };
|
|
229
|
-
//# sourceMappingURL=api.d.ts.map
|
|
228
|
+
export { AggregatePaginationResponse, ApiResponse, BaseApi, BaseApiConfig, DeleteResponse, ExtractDoc, FilterOperator, KeysetPaginationResponse, OffsetPaginationResponse, PaginatedResponse, PopulateOption, QueryParams, RequestOptions, SortDirection, SortSpec, createCrudApi, isAggregatePagination, isKeysetPagination, isOffsetPagination };
|
package/dist/api.js
CHANGED
|
@@ -57,7 +57,11 @@ var BaseApi = class {
|
|
|
57
57
|
return result;
|
|
58
58
|
}
|
|
59
59
|
async getAll({ token = null, organizationId = null, params = {}, options = {} } = {}) {
|
|
60
|
-
const
|
|
60
|
+
const mergedParams = {
|
|
61
|
+
...this.config.defaultParams,
|
|
62
|
+
...params
|
|
63
|
+
};
|
|
64
|
+
const processedParams = this.prepareParams(mergedParams);
|
|
61
65
|
const queryString = this.createQueryString(processedParams);
|
|
62
66
|
const requestOptions = {
|
|
63
67
|
cache: this.config.cache,
|
|
@@ -118,6 +122,7 @@ var BaseApi = class {
|
|
|
118
122
|
}
|
|
119
123
|
async search({ token = null, organizationId = null, searchParams = {}, params = {}, options = {} } = {}) {
|
|
120
124
|
const queryParams = {
|
|
125
|
+
...this.config.defaultParams,
|
|
121
126
|
...params,
|
|
122
127
|
...searchParams
|
|
123
128
|
};
|
|
@@ -133,7 +138,10 @@ var BaseApi = class {
|
|
|
133
138
|
}
|
|
134
139
|
async findBy({ token = null, organizationId = null, field, value, operator, params = {}, options = {} }) {
|
|
135
140
|
if (!field || value === void 0) throw new Error("Field and value are required");
|
|
136
|
-
const queryParams = {
|
|
141
|
+
const queryParams = {
|
|
142
|
+
...this.config.defaultParams,
|
|
143
|
+
...params
|
|
144
|
+
};
|
|
137
145
|
if (operator) queryParams[`${field}[${operator}]`] = Array.isArray(value) ? value.join(",") : value;
|
|
138
146
|
else queryParams[field] = value;
|
|
139
147
|
const processedParams = this.prepareParams(queryParams);
|
|
@@ -176,5 +184,4 @@ function isAggregatePagination(response) {
|
|
|
176
184
|
}
|
|
177
185
|
|
|
178
186
|
//#endregion
|
|
179
|
-
export { BaseApi, createCrudApi, isAggregatePagination, isKeysetPagination, isOffsetPagination };
|
|
180
|
-
//# sourceMappingURL=api.js.map
|
|
187
|
+
export { BaseApi, createCrudApi, isAggregatePagination, isKeysetPagination, isOffsetPagination };
|
package/dist/client.d.ts
CHANGED
|
@@ -56,10 +56,25 @@ interface ClientConfig {
|
|
|
56
56
|
* - 'cookie': Auth is handled via HTTP-only cookies (e.g. Better Auth). Queries are always enabled — no token needed.
|
|
57
57
|
*/
|
|
58
58
|
authMode?: 'bearer' | 'cookie';
|
|
59
|
+
/**
|
|
60
|
+
* Fetch credentials policy.
|
|
61
|
+
* - 'include': Always send cookies cross-origin (required for cookie-based auth).
|
|
62
|
+
* - 'same-origin': Only send cookies to same-origin requests (browser default).
|
|
63
|
+
* - 'omit': Never send cookies.
|
|
64
|
+
*
|
|
65
|
+
* When not set, derived from `authMode`:
|
|
66
|
+
* - `authMode: 'cookie'` → `'include'`
|
|
67
|
+
* - `authMode: 'bearer'` (default) → `'same-origin'`
|
|
68
|
+
*/
|
|
69
|
+
credentials?: RequestCredentials;
|
|
59
70
|
}
|
|
60
71
|
/**
|
|
61
72
|
* Configure the API client. Call once at app init before any API requests.
|
|
62
73
|
*
|
|
74
|
+
* **SSR safety:** This sets module-level state. In Next.js, call this only in
|
|
75
|
+
* client-side code (e.g. a `"use client"` provider or `useEffect`).
|
|
76
|
+
* Calling on the server risks leaking state between requests.
|
|
77
|
+
*
|
|
63
78
|
* @example
|
|
64
79
|
* // Bearer token auth (default)
|
|
65
80
|
* configureClient({ baseUrl: process.env.NEXT_PUBLIC_API_URL! });
|
|
@@ -80,6 +95,8 @@ interface AuthConfig {
|
|
|
80
95
|
* Configure auth context for automatic token/orgId injection.
|
|
81
96
|
* When configured, hooks auto-inject these values so you don't need to pass them manually.
|
|
82
97
|
*
|
|
98
|
+
* **SSR safety:** This sets module-level state. Call only in client-side code.
|
|
99
|
+
*
|
|
83
100
|
* @example
|
|
84
101
|
* // Cookie auth (no token needed)
|
|
85
102
|
* configureAuth({ getOrgId: () => currentOrg.id });
|
|
@@ -168,5 +185,4 @@ declare function handleApiRequest<T = unknown>(method: HttpMethod, endpoint: str
|
|
|
168
185
|
*/
|
|
169
186
|
declare function createQueryString<T extends Record<string, unknown>>(params?: T): string;
|
|
170
187
|
//#endregion
|
|
171
|
-
export { ApiRequestOptions, ArcApiError, ArcApiErrorOptions, ArcClient, ArcClientConfig, AuthConfig, BlobResponse, ClientConfig, HttpMethod, TextResponse, ToastHandler, UseRouterHook, configureAuth, configureClient, createClient, createQueryString, getAuthContext, getAuthMode, handleApiRequest, isArcApiError };
|
|
172
|
-
//# sourceMappingURL=client.d.ts.map
|
|
188
|
+
export { ApiRequestOptions, ArcApiError, ArcApiErrorOptions, ArcClient, ArcClientConfig, AuthConfig, BlobResponse, ClientConfig, HttpMethod, TextResponse, ToastHandler, UseRouterHook, configureAuth, configureClient, createClient, createQueryString, getAuthContext, getAuthMode, handleApiRequest, isArcApiError };
|
package/dist/client.js
CHANGED
|
@@ -43,6 +43,10 @@ let clientConfig = null;
|
|
|
43
43
|
/**
|
|
44
44
|
* Configure the API client. Call once at app init before any API requests.
|
|
45
45
|
*
|
|
46
|
+
* **SSR safety:** This sets module-level state. In Next.js, call this only in
|
|
47
|
+
* client-side code (e.g. a `"use client"` provider or `useEffect`).
|
|
48
|
+
* Calling on the server risks leaking state between requests.
|
|
49
|
+
*
|
|
46
50
|
* @example
|
|
47
51
|
* // Bearer token auth (default)
|
|
48
52
|
* configureClient({ baseUrl: process.env.NEXT_PUBLIC_API_URL! });
|
|
@@ -64,6 +68,8 @@ let authConfig = null;
|
|
|
64
68
|
* Configure auth context for automatic token/orgId injection.
|
|
65
69
|
* When configured, hooks auto-inject these values so you don't need to pass them manually.
|
|
66
70
|
*
|
|
71
|
+
* **SSR safety:** This sets module-level state. Call only in client-side code.
|
|
72
|
+
*
|
|
67
73
|
* @example
|
|
68
74
|
* // Cookie auth (no token needed)
|
|
69
75
|
* configureAuth({ getOrgId: () => currentOrg.id });
|
|
@@ -122,10 +128,11 @@ async function executeRequest(config, method, endpoint, options = {}) {
|
|
|
122
128
|
...headers,
|
|
123
129
|
...headerOptions
|
|
124
130
|
};
|
|
131
|
+
const credentials = config.credentials ?? (config.authMode === "cookie" ? "include" : "same-origin");
|
|
125
132
|
const fetchOptions = {
|
|
126
133
|
method,
|
|
127
134
|
headers,
|
|
128
|
-
credentials
|
|
135
|
+
credentials,
|
|
129
136
|
...signal ? { signal } : {}
|
|
130
137
|
};
|
|
131
138
|
if (body !== void 0 && body !== null) fetchOptions.body = body instanceof FormData ? body : JSON.stringify(body);
|
|
@@ -177,8 +184,8 @@ async function executeRequest(config, method, endpoint, options = {}) {
|
|
|
177
184
|
}
|
|
178
185
|
return data;
|
|
179
186
|
} catch (error) {
|
|
180
|
-
if (error instanceof
|
|
181
|
-
throw new Error(
|
|
187
|
+
if (error instanceof Error) throw error;
|
|
188
|
+
throw new Error("An error occurred while fetching data.");
|
|
182
189
|
}
|
|
183
190
|
}
|
|
184
191
|
/**
|
|
@@ -238,5 +245,4 @@ function createQueryString(params = {}) {
|
|
|
238
245
|
}
|
|
239
246
|
|
|
240
247
|
//#endregion
|
|
241
|
-
export { ArcApiError, configureAuth, configureClient, createClient, createQueryString, getAuthContext, getAuthMode, handleApiRequest, isArcApiError };
|
|
242
|
-
//# sourceMappingURL=client.js.map
|
|
248
|
+
export { ArcApiError, configureAuth, configureClient, createClient, createQueryString, getAuthContext, getAuthMode, handleApiRequest, isArcApiError };
|
package/dist/hooks.d.ts
CHANGED
|
@@ -1,65 +1,21 @@
|
|
|
1
1
|
import { ArcClient, UseRouterHook } from "./client.js";
|
|
2
|
+
import { BaseApi } from "./api.js";
|
|
2
3
|
import { MutationCallbacks, MutationMessages, TransitionMutationReturn } from "./mutation.js";
|
|
3
4
|
import { CacheUtils, DetailQueryOptions, DetailQueryResult, InfiniteListQueryOptions, InfiniteListQueryResult, ListQueryOptions, ListQueryResult, QueryKeys } from "./query.js";
|
|
4
5
|
import { QueryKey } from "@tanstack/react-query";
|
|
5
6
|
|
|
6
7
|
//#region src/hooks.d.ts
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
id: string;
|
|
19
|
-
token?: string | null;
|
|
20
|
-
organizationId?: string | null;
|
|
21
|
-
params?: {
|
|
22
|
-
select?: string;
|
|
23
|
-
populate?: string | string[];
|
|
24
|
-
};
|
|
25
|
-
options?: {
|
|
26
|
-
signal?: AbortSignal;
|
|
27
|
-
[key: string]: unknown;
|
|
28
|
-
};
|
|
29
|
-
}) => Promise<unknown>;
|
|
30
|
-
create: (options: {
|
|
31
|
-
token?: string | null;
|
|
32
|
-
organizationId?: string | null;
|
|
33
|
-
data: TCreate;
|
|
34
|
-
}) => Promise<unknown>;
|
|
35
|
-
update: (options: {
|
|
36
|
-
token?: string | null;
|
|
37
|
-
organizationId?: string | null;
|
|
38
|
-
id: string;
|
|
39
|
-
data: TUpdate;
|
|
40
|
-
}) => Promise<unknown>;
|
|
41
|
-
delete: (options: {
|
|
42
|
-
token?: string | null;
|
|
43
|
-
organizationId?: string | null;
|
|
44
|
-
id: string;
|
|
45
|
-
}) => Promise<unknown>;
|
|
46
|
-
upload?: (options: {
|
|
47
|
-
token?: string | null;
|
|
48
|
-
organizationId?: string | null;
|
|
49
|
-
data: FormData;
|
|
50
|
-
id?: string;
|
|
51
|
-
path?: string;
|
|
52
|
-
}) => Promise<unknown>;
|
|
53
|
-
search?: (options: {
|
|
54
|
-
token?: string | null;
|
|
55
|
-
organizationId?: string | null;
|
|
56
|
-
params?: Record<string, unknown>;
|
|
57
|
-
options?: {
|
|
58
|
-
signal?: AbortSignal;
|
|
59
|
-
[key: string]: unknown;
|
|
60
|
-
};
|
|
61
|
-
}) => Promise<unknown>;
|
|
62
|
-
}
|
|
8
|
+
/**
|
|
9
|
+
* CRUD API interface accepted by createCrudHooks.
|
|
10
|
+
*
|
|
11
|
+
* Derived from BaseApi via Pick so the types are always in sync.
|
|
12
|
+
* BaseApi instances satisfy this exactly (same source of truth).
|
|
13
|
+
* Custom implementations just need to match BaseApi's method signatures.
|
|
14
|
+
*/
|
|
15
|
+
type CrudApi<T = unknown, TCreate = Partial<T>, TUpdate = Partial<T>> = Pick<BaseApi<T, TCreate, TUpdate>, 'getAll' | 'getById' | 'create' | 'update' | 'delete'> & {
|
|
16
|
+
upload?: BaseApi<T, TCreate, TUpdate>['upload'];
|
|
17
|
+
search?: BaseApi<T, TCreate, TUpdate>['search'];
|
|
18
|
+
};
|
|
63
19
|
interface CrudHooksConfig<T, TCreate = Partial<T>, TUpdate = Partial<T>> {
|
|
64
20
|
api: CrudApi<T, TCreate, TUpdate>;
|
|
65
21
|
entityKey: string;
|
|
@@ -167,6 +123,8 @@ interface CrudHooksReturn<T, TCreate, TUpdate> {
|
|
|
167
123
|
/**
|
|
168
124
|
* Configure the router hook for useNavigation. Call once at app init.
|
|
169
125
|
*
|
|
126
|
+
* **SSR safety:** This sets module-level state. Call only in client-side code.
|
|
127
|
+
*
|
|
170
128
|
* @example
|
|
171
129
|
* import { useRouter } from "next/navigation";
|
|
172
130
|
* configureNavigation(useRouter);
|
|
@@ -181,5 +139,4 @@ declare function createCrudHooks<T, TCreate = Partial<T>, TUpdate = Partial<T>>(
|
|
|
181
139
|
client
|
|
182
140
|
}: CrudHooksConfig<T, TCreate, TUpdate>): CrudHooksReturn<T, TCreate, TUpdate>;
|
|
183
141
|
//#endregion
|
|
184
|
-
export { CallOptions, CrudActions, CrudApi, CrudHooksConfig, CrudHooksReturn, DeleteParams, MutationParams, NavigateFn, NavigationOptions, UpdateParams,
|
|
185
|
-
//# sourceMappingURL=hooks.d.ts.map
|
|
142
|
+
export { CallOptions, CrudActions, CrudApi, CrudHooksConfig, CrudHooksReturn, DeleteParams, MutationParams, NavigateFn, NavigationOptions, UpdateParams, configureNavigation, createCrudHooks };
|