routesync 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.
- package/README.md +289 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +436 -0
- package/dist/core.d.mts +206 -0
- package/dist/core.d.ts +206 -0
- package/dist/core.js +353 -0
- package/dist/core.mjs +307 -0
- package/dist/react.d.mts +95 -0
- package/dist/react.d.ts +95 -0
- package/dist/react.js +77 -0
- package/dist/react.mjs +48 -0
- package/dist/sdk.d.mts +269 -0
- package/dist/sdk.d.ts +269 -0
- package/dist/sdk.js +519 -0
- package/dist/sdk.mjs +476 -0
- package/dist/vue.d.mts +108 -0
- package/dist/vue.d.ts +108 -0
- package/dist/vue.js +66 -0
- package/dist/vue.mjs +40 -0
- package/package.json +98 -0
package/dist/sdk.js
ADDED
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// packages/sdk/src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
GenericService: () => GenericService,
|
|
34
|
+
camelToSnakeKey: () => camelToSnakeKey,
|
|
35
|
+
createClient: () => createClient,
|
|
36
|
+
createHttpClient: () => createClient2,
|
|
37
|
+
createService: () => createService,
|
|
38
|
+
defineApi: () => defineApi,
|
|
39
|
+
endpoint: () => endpoint,
|
|
40
|
+
generateHooks: () => generateHooks,
|
|
41
|
+
mapKeysDeep: () => mapKeysDeep,
|
|
42
|
+
parseWithSchema: () => parseWithSchema,
|
|
43
|
+
resource: () => resource,
|
|
44
|
+
snakeToCamelKey: () => snakeToCamelKey,
|
|
45
|
+
toCamelCase: () => toCamelCase,
|
|
46
|
+
toSnakeCase: () => toSnakeCase
|
|
47
|
+
});
|
|
48
|
+
module.exports = __toCommonJS(src_exports);
|
|
49
|
+
|
|
50
|
+
// packages/core/src/client/HttpClient.ts
|
|
51
|
+
var import_axios = __toESM(require("axios"));
|
|
52
|
+
var HttpClient = class {
|
|
53
|
+
constructor(config) {
|
|
54
|
+
this.client = import_axios.default.create({
|
|
55
|
+
baseURL: config.baseURL,
|
|
56
|
+
timeout: config.timeout ?? 1e4,
|
|
57
|
+
headers: {
|
|
58
|
+
"Content-Type": "application/json",
|
|
59
|
+
...config.headers ?? {}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
if (config.token) {
|
|
63
|
+
this.setToken(config.token);
|
|
64
|
+
}
|
|
65
|
+
this.setupInterceptors();
|
|
66
|
+
}
|
|
67
|
+
setupInterceptors() {
|
|
68
|
+
this.client.interceptors.response.use(
|
|
69
|
+
(response) => response,
|
|
70
|
+
(error) => {
|
|
71
|
+
const message = error.response?.data?.message ?? error.message ?? "Unknown error";
|
|
72
|
+
return Promise.reject({
|
|
73
|
+
success: false,
|
|
74
|
+
message,
|
|
75
|
+
status: error.response?.status,
|
|
76
|
+
errors: error.response?.data?.errors
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
setToken(token) {
|
|
82
|
+
this.client.defaults.headers.common["Authorization"] = `Bearer ${token}`;
|
|
83
|
+
}
|
|
84
|
+
removeToken() {
|
|
85
|
+
delete this.client.defaults.headers.common["Authorization"];
|
|
86
|
+
}
|
|
87
|
+
async get(url, config) {
|
|
88
|
+
const response = await this.client.get(url, config);
|
|
89
|
+
return response.data;
|
|
90
|
+
}
|
|
91
|
+
async post(url, body, config) {
|
|
92
|
+
const response = await this.client.post(url, body, config);
|
|
93
|
+
return response.data;
|
|
94
|
+
}
|
|
95
|
+
async put(url, body, config) {
|
|
96
|
+
const response = await this.client.put(url, body, config);
|
|
97
|
+
return response.data;
|
|
98
|
+
}
|
|
99
|
+
async patch(url, body, config) {
|
|
100
|
+
const response = await this.client.patch(url, body, config);
|
|
101
|
+
return response.data;
|
|
102
|
+
}
|
|
103
|
+
async delete(url, config) {
|
|
104
|
+
const response = await this.client.delete(url, config);
|
|
105
|
+
return response.data;
|
|
106
|
+
}
|
|
107
|
+
async upload(url, formData) {
|
|
108
|
+
const response = await this.client.post(url, formData, {
|
|
109
|
+
headers: { "Content-Type": "multipart/form-data" }
|
|
110
|
+
});
|
|
111
|
+
return response.data;
|
|
112
|
+
}
|
|
113
|
+
getInstance() {
|
|
114
|
+
return this.client;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// packages/core/src/auth/TokenManager.ts
|
|
119
|
+
var _TokenManager = class _TokenManager {
|
|
120
|
+
constructor() {
|
|
121
|
+
this.token = null;
|
|
122
|
+
}
|
|
123
|
+
set(token) {
|
|
124
|
+
this.token = token;
|
|
125
|
+
if (typeof localStorage !== "undefined") {
|
|
126
|
+
localStorage.setItem(_TokenManager.TOKEN_KEY, token);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
get() {
|
|
130
|
+
if (this.token) return this.token;
|
|
131
|
+
if (typeof localStorage !== "undefined") {
|
|
132
|
+
return localStorage.getItem(_TokenManager.TOKEN_KEY);
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
clear() {
|
|
137
|
+
this.token = null;
|
|
138
|
+
if (typeof localStorage !== "undefined") {
|
|
139
|
+
localStorage.removeItem(_TokenManager.TOKEN_KEY);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
exists() {
|
|
143
|
+
return this.get() !== null;
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
_TokenManager.TOKEN_KEY = "routesync_token";
|
|
147
|
+
var TokenManager = _TokenManager;
|
|
148
|
+
|
|
149
|
+
// packages/core/src/routing/PathResolver.ts
|
|
150
|
+
var PathResolver = class {
|
|
151
|
+
/**
|
|
152
|
+
* Resolve path params.
|
|
153
|
+
* e.g. resolvePath('/produk/:id', { id: 10 }) => '/produk/10'
|
|
154
|
+
*/
|
|
155
|
+
static resolve(path, params) {
|
|
156
|
+
if (!params) return path;
|
|
157
|
+
let resolved = path;
|
|
158
|
+
for (const [key, value] of Object.entries(params)) {
|
|
159
|
+
resolved = resolved.replace(`:${key}`, String(value));
|
|
160
|
+
}
|
|
161
|
+
const unresolved = resolved.match(/:([a-zA-Z_]+)/g);
|
|
162
|
+
if (unresolved) {
|
|
163
|
+
throw new Error(
|
|
164
|
+
`Unresolved path params: ${unresolved.join(", ")}`
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
return resolved;
|
|
168
|
+
}
|
|
169
|
+
static extractParams(path) {
|
|
170
|
+
const matches = path.match(/:([a-zA-Z_]+)/g) ?? [];
|
|
171
|
+
return matches.map((m) => m.slice(1));
|
|
172
|
+
}
|
|
173
|
+
static hasParams(path) {
|
|
174
|
+
return /:([a-zA-Z_]+)/.test(path);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// packages/sdk/src/mappers/schema.ts
|
|
179
|
+
function parseWithSchema(schema, value) {
|
|
180
|
+
if (!schema) return value;
|
|
181
|
+
if (typeof schema === "function") {
|
|
182
|
+
return schema(value);
|
|
183
|
+
}
|
|
184
|
+
if (schema.safeParse) {
|
|
185
|
+
const result = schema.safeParse(value);
|
|
186
|
+
if (result.success) return result.data;
|
|
187
|
+
throw result.error;
|
|
188
|
+
}
|
|
189
|
+
if (schema.parse) {
|
|
190
|
+
return schema.parse(value);
|
|
191
|
+
}
|
|
192
|
+
return value;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// packages/sdk/src/defineApi.ts
|
|
196
|
+
var _client = null;
|
|
197
|
+
function getClient() {
|
|
198
|
+
if (!_client) {
|
|
199
|
+
throw new Error("RouteSync not initialized. Call createClient() first.");
|
|
200
|
+
}
|
|
201
|
+
return _client;
|
|
202
|
+
}
|
|
203
|
+
function createClient(config) {
|
|
204
|
+
_client = new HttpClient(config);
|
|
205
|
+
return _client;
|
|
206
|
+
}
|
|
207
|
+
function defineApi(definition, config) {
|
|
208
|
+
if (config) {
|
|
209
|
+
createClient(config);
|
|
210
|
+
}
|
|
211
|
+
const proxy = {};
|
|
212
|
+
for (const group in definition) {
|
|
213
|
+
const groupDef = definition[group];
|
|
214
|
+
const groupProxy = {};
|
|
215
|
+
for (const action in groupDef) {
|
|
216
|
+
const route = groupDef[action];
|
|
217
|
+
const callable = async (options) => {
|
|
218
|
+
const client = getClient();
|
|
219
|
+
const params = applyMapper(
|
|
220
|
+
route,
|
|
221
|
+
"params",
|
|
222
|
+
parseRouteSchema(route, "params", options?.params)
|
|
223
|
+
);
|
|
224
|
+
const query = applyMapper(
|
|
225
|
+
route,
|
|
226
|
+
"query",
|
|
227
|
+
parseRouteSchema(route, "query", options?.query)
|
|
228
|
+
);
|
|
229
|
+
const body = applyMapper(
|
|
230
|
+
route,
|
|
231
|
+
"body",
|
|
232
|
+
parseRouteSchema(route, "body", options?.body)
|
|
233
|
+
);
|
|
234
|
+
const resolvedPath = PathResolver.resolve(route.path, params);
|
|
235
|
+
const method = route.method.toLowerCase();
|
|
236
|
+
const requestConfig = { params: query, headers: route.headers };
|
|
237
|
+
let response;
|
|
238
|
+
if (method === "get" || method === "delete") {
|
|
239
|
+
response = await client[method](resolvedPath, requestConfig);
|
|
240
|
+
} else {
|
|
241
|
+
response = await client[method](resolvedPath, body, requestConfig);
|
|
242
|
+
}
|
|
243
|
+
return applyMapper(
|
|
244
|
+
route,
|
|
245
|
+
"response",
|
|
246
|
+
parseRouteSchema(route, "response", response)
|
|
247
|
+
);
|
|
248
|
+
};
|
|
249
|
+
callable.$def = route;
|
|
250
|
+
callable.$key = [group, action];
|
|
251
|
+
groupProxy[action] = callable;
|
|
252
|
+
}
|
|
253
|
+
;
|
|
254
|
+
proxy[group] = groupProxy;
|
|
255
|
+
}
|
|
256
|
+
return proxy;
|
|
257
|
+
}
|
|
258
|
+
var routeSchemaKeys = ["params", "query", "body", "request", "response"];
|
|
259
|
+
function parseRouteSchema(route, part, value) {
|
|
260
|
+
if (value === void 0) return void 0;
|
|
261
|
+
const schema = pickRouteSchema(route, part);
|
|
262
|
+
return parseWithSchema(schema, value);
|
|
263
|
+
}
|
|
264
|
+
function pickRouteSchema(route, part) {
|
|
265
|
+
const schema = route.schema;
|
|
266
|
+
if (!schema) return void 0;
|
|
267
|
+
if (hasRouteSchemaKeys(schema)) {
|
|
268
|
+
return schema[part] ?? (part === "body" ? schema.request : void 0);
|
|
269
|
+
}
|
|
270
|
+
return defaultSchemaPart(route.method) === part ? schema : void 0;
|
|
271
|
+
}
|
|
272
|
+
function hasRouteSchemaKeys(value) {
|
|
273
|
+
return Boolean(
|
|
274
|
+
value && typeof value === "object" && routeSchemaKeys.some((key) => key in value)
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
function defaultSchemaPart(method) {
|
|
278
|
+
return method === "GET" || method === "DELETE" ? "response" : "body";
|
|
279
|
+
}
|
|
280
|
+
function applyMapper(route, part, value) {
|
|
281
|
+
if (value === void 0 || !route.mapper) return value;
|
|
282
|
+
if (typeof route.mapper === "function") {
|
|
283
|
+
return part === "response" ? route.mapper(value) : value;
|
|
284
|
+
}
|
|
285
|
+
const mapper = route.mapper[part] ?? (part === "body" ? route.mapper.request : void 0);
|
|
286
|
+
return mapper ? mapper(value) : value;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// packages/sdk/src/endpoint.ts
|
|
290
|
+
function endpoint(def) {
|
|
291
|
+
return def;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// packages/sdk/src/resource.ts
|
|
295
|
+
function resource(config) {
|
|
296
|
+
const result = {};
|
|
297
|
+
for (const key in config.endpoints) {
|
|
298
|
+
const ep = config.endpoints[key];
|
|
299
|
+
result[key] = {
|
|
300
|
+
...ep,
|
|
301
|
+
// Endpoint-level overrides cascade defaults, never the other way around
|
|
302
|
+
auth: ep.auth ?? config.auth,
|
|
303
|
+
headers: {
|
|
304
|
+
...config.headers ?? {},
|
|
305
|
+
...ep.headers ?? {}
|
|
306
|
+
},
|
|
307
|
+
cache: ep.cache ?? config.cache,
|
|
308
|
+
retry: ep.retry ?? config.retry
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
return result;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// packages/sdk/src/mappers/case.ts
|
|
315
|
+
function snakeToCamelKey(key) {
|
|
316
|
+
return key.replace(/_([a-zA-Z0-9])/g, (_, char) => char.toUpperCase());
|
|
317
|
+
}
|
|
318
|
+
function camelToSnakeKey(key) {
|
|
319
|
+
return key.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").toLowerCase();
|
|
320
|
+
}
|
|
321
|
+
function isPlainObject(value) {
|
|
322
|
+
return Object.prototype.toString.call(value) === "[object Object]";
|
|
323
|
+
}
|
|
324
|
+
function mapKeysDeep(value, keyCase) {
|
|
325
|
+
if (Array.isArray(value)) {
|
|
326
|
+
return value.map((item) => mapKeysDeep(item, keyCase));
|
|
327
|
+
}
|
|
328
|
+
if (!isPlainObject(value)) {
|
|
329
|
+
return value;
|
|
330
|
+
}
|
|
331
|
+
const mapper = keyCase === "camel" ? snakeToCamelKey : camelToSnakeKey;
|
|
332
|
+
const mapped = {};
|
|
333
|
+
for (const [key, child] of Object.entries(value)) {
|
|
334
|
+
mapped[mapper(key)] = mapKeysDeep(child, keyCase);
|
|
335
|
+
}
|
|
336
|
+
return mapped;
|
|
337
|
+
}
|
|
338
|
+
function toCamelCase(value) {
|
|
339
|
+
return mapKeysDeep(value, "camel");
|
|
340
|
+
}
|
|
341
|
+
function toSnakeCase(value) {
|
|
342
|
+
return mapKeysDeep(value, "snake");
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// packages/sdk/src/createService.ts
|
|
346
|
+
var GenericService = class {
|
|
347
|
+
constructor(client, endpoint2, options = {}) {
|
|
348
|
+
this.client = client;
|
|
349
|
+
this.endpoint = endpoint2;
|
|
350
|
+
this.options = options;
|
|
351
|
+
}
|
|
352
|
+
async findAll(params) {
|
|
353
|
+
const response = await this.client.get(this.endpoint, {
|
|
354
|
+
params: this.mapRequest(params)
|
|
355
|
+
});
|
|
356
|
+
const items = parseWithSchema(this.options.listSchema, this.extractData(response));
|
|
357
|
+
return items.map((item) => this.mapEntity(item));
|
|
358
|
+
}
|
|
359
|
+
async findById(id, params) {
|
|
360
|
+
const response = await this.client.get(`${this.endpoint}/${id}`, {
|
|
361
|
+
params: this.mapRequest(params)
|
|
362
|
+
});
|
|
363
|
+
return this.mapEntity(this.parseEntity(this.extractData(response)));
|
|
364
|
+
}
|
|
365
|
+
async create(payload) {
|
|
366
|
+
const validated = parseWithSchema(this.options.createSchema, payload);
|
|
367
|
+
const response = await this.client.post(this.endpoint, this.mapRequest(validated));
|
|
368
|
+
return this.mapEntity(this.parseEntity(this.extractData(response)));
|
|
369
|
+
}
|
|
370
|
+
async update(id, payload) {
|
|
371
|
+
const validated = parseWithSchema(this.options.updateSchema, payload);
|
|
372
|
+
const response = await this.client.put(
|
|
373
|
+
`${this.endpoint}/${id}`,
|
|
374
|
+
this.mapRequest(validated)
|
|
375
|
+
);
|
|
376
|
+
return this.mapEntity(this.parseEntity(this.extractData(response)));
|
|
377
|
+
}
|
|
378
|
+
async patch(id, payload) {
|
|
379
|
+
const validated = parseWithSchema(this.options.updateSchema, payload);
|
|
380
|
+
const response = await this.client.patch(
|
|
381
|
+
`${this.endpoint}/${id}`,
|
|
382
|
+
this.mapRequest(validated)
|
|
383
|
+
);
|
|
384
|
+
return this.mapEntity(this.parseEntity(this.extractData(response)));
|
|
385
|
+
}
|
|
386
|
+
async delete(id) {
|
|
387
|
+
const response = await this.client.delete(`${this.endpoint}/${id}`);
|
|
388
|
+
return this.extractData(response);
|
|
389
|
+
}
|
|
390
|
+
async upload(file) {
|
|
391
|
+
const response = await this.client.upload(`${this.endpoint}/upload`, file);
|
|
392
|
+
return this.mapEntity(this.parseEntity(this.extractData(response)));
|
|
393
|
+
}
|
|
394
|
+
extractData(response) {
|
|
395
|
+
if (response && typeof response === "object" && "data" in response) {
|
|
396
|
+
return response.data;
|
|
397
|
+
}
|
|
398
|
+
return response;
|
|
399
|
+
}
|
|
400
|
+
parseEntity(value) {
|
|
401
|
+
return parseWithSchema(this.options.entitySchema, value);
|
|
402
|
+
}
|
|
403
|
+
mapEntity(value) {
|
|
404
|
+
if (this.options.fromBackend) {
|
|
405
|
+
return this.options.fromBackend(value);
|
|
406
|
+
}
|
|
407
|
+
if (this.options.mapResponseKeys === false) {
|
|
408
|
+
return value;
|
|
409
|
+
}
|
|
410
|
+
return toCamelCase(value);
|
|
411
|
+
}
|
|
412
|
+
mapRequest(value) {
|
|
413
|
+
if (value === void 0) return void 0;
|
|
414
|
+
if (this.options.toBackend) {
|
|
415
|
+
return this.options.toBackend(value);
|
|
416
|
+
}
|
|
417
|
+
if (this.options.mapRequestKeys === false) {
|
|
418
|
+
return value;
|
|
419
|
+
}
|
|
420
|
+
return toSnakeCase(value);
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
function createService(client, endpoint2, options) {
|
|
424
|
+
return new GenericService(
|
|
425
|
+
client,
|
|
426
|
+
endpoint2,
|
|
427
|
+
options
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// packages/sdk/src/createClient.ts
|
|
432
|
+
function createClient2(config) {
|
|
433
|
+
const client = new HttpClient(config);
|
|
434
|
+
const tokenManager = new TokenManager();
|
|
435
|
+
if (config.token) {
|
|
436
|
+
tokenManager.set(config.token);
|
|
437
|
+
}
|
|
438
|
+
return {
|
|
439
|
+
client,
|
|
440
|
+
tokenManager,
|
|
441
|
+
setToken(token) {
|
|
442
|
+
tokenManager.set(token);
|
|
443
|
+
client.setToken(token);
|
|
444
|
+
},
|
|
445
|
+
clearToken() {
|
|
446
|
+
tokenManager.clear();
|
|
447
|
+
client.removeToken();
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// packages/sdk/src/generateHooks.ts
|
|
453
|
+
function generateHooks(api) {
|
|
454
|
+
let useQuery;
|
|
455
|
+
let useMutation;
|
|
456
|
+
let useQueryClient;
|
|
457
|
+
try {
|
|
458
|
+
const rq = require("@tanstack/react-query");
|
|
459
|
+
useQuery = rq.useQuery;
|
|
460
|
+
useMutation = rq.useMutation;
|
|
461
|
+
useQueryClient = rq.useQueryClient;
|
|
462
|
+
} catch {
|
|
463
|
+
throw new Error(
|
|
464
|
+
"@tanstack/react-query is required to use generateHooks. Install it with: npm install @tanstack/react-query"
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
const hooks = {};
|
|
468
|
+
for (const [group, actions] of Object.entries(api)) {
|
|
469
|
+
for (const [action, endpoint2] of Object.entries(actions)) {
|
|
470
|
+
const method = endpoint2.$def.method;
|
|
471
|
+
const hookName = toHookName(group, action);
|
|
472
|
+
if (method === "GET" || method === "DELETE") {
|
|
473
|
+
hooks[hookName] = (options, queryOptions) => useQuery({
|
|
474
|
+
queryKey: options ? [...endpoint2.$key, options] : endpoint2.$key,
|
|
475
|
+
queryFn: () => endpoint2(options),
|
|
476
|
+
...queryOptions
|
|
477
|
+
});
|
|
478
|
+
} else {
|
|
479
|
+
hooks[hookName] = (mutationOptions) => {
|
|
480
|
+
const qc = useQueryClient();
|
|
481
|
+
return useMutation({
|
|
482
|
+
...mutationOptions,
|
|
483
|
+
mutationFn: (options) => endpoint2(options),
|
|
484
|
+
onSuccess: (...args) => {
|
|
485
|
+
qc.invalidateQueries({ queryKey: [group] });
|
|
486
|
+
mutationOptions?.invalidate?.forEach((ep) => {
|
|
487
|
+
qc.invalidateQueries({ queryKey: ep.$key });
|
|
488
|
+
});
|
|
489
|
+
mutationOptions?.onSuccess?.(...args);
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
return hooks;
|
|
497
|
+
}
|
|
498
|
+
function toHookName(group, action) {
|
|
499
|
+
const g = group.charAt(0).toUpperCase() + group.slice(1);
|
|
500
|
+
const a = action.charAt(0).toUpperCase() + action.slice(1);
|
|
501
|
+
return `use${g}${a}`;
|
|
502
|
+
}
|
|
503
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
504
|
+
0 && (module.exports = {
|
|
505
|
+
GenericService,
|
|
506
|
+
camelToSnakeKey,
|
|
507
|
+
createClient,
|
|
508
|
+
createHttpClient,
|
|
509
|
+
createService,
|
|
510
|
+
defineApi,
|
|
511
|
+
endpoint,
|
|
512
|
+
generateHooks,
|
|
513
|
+
mapKeysDeep,
|
|
514
|
+
parseWithSchema,
|
|
515
|
+
resource,
|
|
516
|
+
snakeToCamelKey,
|
|
517
|
+
toCamelCase,
|
|
518
|
+
toSnakeCase
|
|
519
|
+
});
|