@bookinglab/booking-journey-api 1.0.0 → 1.1.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/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var react = require('react');
4
- var jsxRuntime = require('react/jsx-runtime');
5
4
  var reactQuery = require('@tanstack/react-query');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
6
 
7
7
  // src/core.ts
8
8
  var ApiClient = class {
@@ -144,6 +144,67 @@ var ApiClient = class {
144
144
  }
145
145
  };
146
146
 
147
+ // src/booking-lab.ts
148
+ var BookingLabClient = class extends ApiClient {
149
+ /**
150
+ * Get all bookings
151
+ */
152
+ async getBookings(userId) {
153
+ return this.get("/bookings", {
154
+ params: userId ? { userId } : void 0
155
+ });
156
+ }
157
+ /**
158
+ * Get a single booking by ID
159
+ */
160
+ async getBooking(bookingId) {
161
+ return this.get(`/bookings/${bookingId}`);
162
+ }
163
+ /**
164
+ * Create a new booking
165
+ */
166
+ async createBooking(booking) {
167
+ return this.post("/bookings", booking);
168
+ }
169
+ /**
170
+ * Update an existing booking
171
+ */
172
+ async updateBooking(bookingId, updates) {
173
+ return this.put(`/bookings/${bookingId}`, updates);
174
+ }
175
+ /**
176
+ * Cancel a booking
177
+ */
178
+ async cancelBooking(bookingId) {
179
+ return this.put(`/bookings/${bookingId}`, { status: "cancelled" });
180
+ }
181
+ /**
182
+ * Delete a booking
183
+ */
184
+ async deleteBooking(bookingId) {
185
+ return this.delete(`/bookings/${bookingId}`);
186
+ }
187
+ /**
188
+ * Get all services
189
+ */
190
+ async getServices() {
191
+ return this.get("/services");
192
+ }
193
+ /**
194
+ * Get a single service by ID
195
+ */
196
+ async getService(serviceId) {
197
+ return this.get(`/services/${serviceId}`);
198
+ }
199
+ };
200
+ function createBookingLabClient(baseUrl, authToken) {
201
+ const client = new BookingLabClient({ baseUrl });
202
+ if (authToken) {
203
+ client.setAuthToken(authToken);
204
+ }
205
+ return client;
206
+ }
207
+
147
208
  // src/jrni.ts
148
209
  var JrniClient = class extends ApiClient {
149
210
  constructor(baseUrl, config) {
@@ -175,11 +236,31 @@ function createJrniClient(baseUrl, config) {
175
236
  return new JrniClient(baseUrl, config);
176
237
  }
177
238
  var ApiClientContext = react.createContext(void 0);
239
+ var defaultQueryClient = new reactQuery.QueryClient({
240
+ defaultOptions: {
241
+ queries: {
242
+ staleTime: 5 * 60 * 1e3,
243
+ retry: 1
244
+ }
245
+ }
246
+ });
178
247
  function ApiClientProvider({
179
248
  children,
249
+ bookingLabBaseUrl,
180
250
  jrniBaseUrl,
181
- jrniConfig
251
+ jrniConfig,
252
+ authToken,
253
+ queryClient
182
254
  }) {
255
+ const client = queryClient || defaultQueryClient;
256
+ const bookingLabClient = react.useMemo(() => {
257
+ if (!bookingLabBaseUrl) return null;
258
+ const clientInstance = new BookingLabClient({ baseUrl: bookingLabBaseUrl });
259
+ if (authToken) {
260
+ clientInstance.setAuthToken(authToken);
261
+ }
262
+ return clientInstance;
263
+ }, [bookingLabBaseUrl, authToken]);
183
264
  const jrniClient = react.useMemo(() => {
184
265
  if (jrniBaseUrl && jrniConfig) {
185
266
  return new JrniClient(jrniBaseUrl, jrniConfig);
@@ -188,11 +269,12 @@ function ApiClientProvider({
188
269
  }, [jrniBaseUrl, jrniConfig?.appId, jrniConfig?.appKey]);
189
270
  const value = react.useMemo(
190
271
  () => ({
272
+ bookingLabClient,
191
273
  jrniClient
192
274
  }),
193
- [jrniClient]
275
+ [bookingLabClient, jrniClient]
194
276
  );
195
- return /* @__PURE__ */ jsxRuntime.jsx(ApiClientContext.Provider, { value, children });
277
+ return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client, children: /* @__PURE__ */ jsxRuntime.jsx(ApiClientContext.Provider, { value, children }) });
196
278
  }
197
279
  function useApiClientContext() {
198
280
  const context = react.useContext(ApiClientContext);
@@ -201,6 +283,29 @@ function useApiClientContext() {
201
283
  }
202
284
  return context;
203
285
  }
286
+ var BookingLabContext = react.createContext(void 0);
287
+ function BookingLabProvider({
288
+ children,
289
+ baseUrl,
290
+ authToken
291
+ }) {
292
+ const client = react.useMemo(() => {
293
+ const clientInstance = new BookingLabClient({ baseUrl });
294
+ if (authToken) {
295
+ clientInstance.setAuthToken(authToken);
296
+ }
297
+ return clientInstance;
298
+ }, [baseUrl, authToken]);
299
+ const value = react.useMemo(() => ({ client }), [client]);
300
+ return /* @__PURE__ */ jsxRuntime.jsx(BookingLabContext.Provider, { value, children });
301
+ }
302
+ function useBookingLabContext() {
303
+ const context = react.useContext(BookingLabContext);
304
+ if (context === void 0) {
305
+ throw new Error("useBookingLabContext must be used within a BookingLabProvider");
306
+ }
307
+ return context.client;
308
+ }
204
309
  var JrniContext = react.createContext(void 0);
205
310
  function JrniProvider({ children, baseUrl, config }) {
206
311
  const client = react.useMemo(() => {
@@ -218,6 +323,19 @@ function useJrniContext() {
218
323
  }
219
324
 
220
325
  // src/hooks/useApiClient.ts
326
+ function useBookingLabClient() {
327
+ try {
328
+ return useBookingLabContext();
329
+ } catch {
330
+ const context = useApiClientContext();
331
+ if (!context.bookingLabClient) {
332
+ throw new Error(
333
+ "BookingLab client not configured. Wrap your app with ApiClientProvider or BookingLabProvider."
334
+ );
335
+ }
336
+ return context.bookingLabClient;
337
+ }
338
+ }
221
339
  function useJrniClient() {
222
340
  try {
223
341
  return useJrniContext();
@@ -240,15 +358,109 @@ function useLogin() {
240
358
  }
241
359
  });
242
360
  }
361
+ function useBookings(userId) {
362
+ const client = useBookingLabClient();
363
+ return reactQuery.useQuery({
364
+ queryKey: ["bookings", userId],
365
+ queryFn: async () => {
366
+ const response = await client.getBookings(userId);
367
+ return response.data;
368
+ }
369
+ });
370
+ }
371
+ function useBooking(bookingId) {
372
+ const client = useBookingLabClient();
373
+ return reactQuery.useQuery({
374
+ queryKey: ["booking", bookingId],
375
+ queryFn: async () => {
376
+ const response = await client.getBooking(bookingId);
377
+ return response.data;
378
+ },
379
+ enabled: !!bookingId
380
+ });
381
+ }
382
+ function useCreateBooking() {
383
+ const client = useBookingLabClient();
384
+ const queryClient = reactQuery.useQueryClient();
385
+ return reactQuery.useMutation({
386
+ mutationFn: async (booking) => {
387
+ const response = await client.createBooking(booking);
388
+ return response.data;
389
+ },
390
+ onSuccess: () => {
391
+ queryClient.invalidateQueries({ queryKey: ["bookings"] });
392
+ }
393
+ });
394
+ }
395
+ function useUpdateBooking() {
396
+ const client = useBookingLabClient();
397
+ const queryClient = reactQuery.useQueryClient();
398
+ return reactQuery.useMutation({
399
+ mutationFn: async ({ id, updates }) => {
400
+ const response = await client.updateBooking(id, updates);
401
+ return response.data;
402
+ },
403
+ onSuccess: (_, variables) => {
404
+ queryClient.invalidateQueries({ queryKey: ["bookings"] });
405
+ queryClient.invalidateQueries({ queryKey: ["booking", variables.id] });
406
+ }
407
+ });
408
+ }
409
+ function useCancelBooking() {
410
+ const client = useBookingLabClient();
411
+ const queryClient = reactQuery.useQueryClient();
412
+ return reactQuery.useMutation({
413
+ mutationFn: async (bookingId) => {
414
+ const response = await client.cancelBooking(bookingId);
415
+ return response.data;
416
+ },
417
+ onSuccess: () => {
418
+ queryClient.invalidateQueries({ queryKey: ["bookings"] });
419
+ }
420
+ });
421
+ }
422
+ function useServices() {
423
+ const client = useBookingLabClient();
424
+ return reactQuery.useQuery({
425
+ queryKey: ["services"],
426
+ queryFn: async () => {
427
+ const response = await client.getServices();
428
+ return response.data;
429
+ }
430
+ });
431
+ }
432
+ function useService(serviceId) {
433
+ const client = useBookingLabClient();
434
+ return reactQuery.useQuery({
435
+ queryKey: ["service", serviceId],
436
+ queryFn: async () => {
437
+ const response = await client.getService(serviceId);
438
+ return response.data;
439
+ },
440
+ enabled: !!serviceId
441
+ });
442
+ }
243
443
 
244
444
  exports.ApiClient = ApiClient;
245
445
  exports.ApiClientProvider = ApiClientProvider;
446
+ exports.BookingLabClient = BookingLabClient;
447
+ exports.BookingLabProvider = BookingLabProvider;
246
448
  exports.JrniClient = JrniClient;
247
449
  exports.JrniProvider = JrniProvider;
450
+ exports.createBookingLabClient = createBookingLabClient;
248
451
  exports.createJrniClient = createJrniClient;
249
452
  exports.useApiClientContext = useApiClientContext;
453
+ exports.useBooking = useBooking;
454
+ exports.useBookingLabClient = useBookingLabClient;
455
+ exports.useBookingLabContext = useBookingLabContext;
456
+ exports.useBookings = useBookings;
457
+ exports.useCancelBooking = useCancelBooking;
458
+ exports.useCreateBooking = useCreateBooking;
250
459
  exports.useJrniClient = useJrniClient;
251
460
  exports.useJrniContext = useJrniContext;
252
461
  exports.useLogin = useLogin;
462
+ exports.useService = useService;
463
+ exports.useServices = useServices;
464
+ exports.useUpdateBooking = useUpdateBooking;
253
465
  //# sourceMappingURL=index.js.map
254
466
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core.ts","../src/jrni.ts","../src/providers/ApiClientProvider.tsx","../src/providers/JrniProvider.tsx","../src/hooks/useApiClient.ts","../src/hooks/useJrni.ts"],"names":["createContext","useMemo","jsx","useContext","useMutation"],"mappings":";;;;;;;AAOO,IAAM,YAAN,MAAgB;AAAA,EAKrB,YAAY,MAAA,EAAyB;AACnC,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,OAAO,EAAE,CAAA;AAC/C,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA,CAAO,OAAA,IAAW,EAAC;AAClC,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,GAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,MAAA,EAAkC;AAC1C,IAAA,IAAI,MAAA,CAAO,SAAS,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,CAAQ,OAAA,CAAQ,OAAO,EAAE,CAAA;AACnE,IAAA,IAAI,MAAA,CAAO,OAAA,EAAS,IAAA,CAAK,OAAA,GAAU,EAAE,GAAG,IAAA,CAAK,OAAA,EAAS,GAAG,MAAA,CAAO,OAAA,EAAQ;AACxE,IAAA,IAAI,MAAA,CAAO,OAAA,EAAS,IAAA,CAAK,OAAA,GAAU,MAAA,CAAO,OAAA;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,KAAA,EAAe;AAC1B,IAAA,IAAA,CAAK,OAAA,CAAQ,eAAe,CAAA,GAAI,CAAA,OAAA,EAAU,KAAK,CAAA,CAAA;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,OAAA,CACd,QAAA,EACA,OAAA,GAA0B,EAAC,EACF;AACzB,IAAA,MAAM,EAAE,MAAA,EAAQ,GAAG,YAAA,EAAa,GAAI,OAAA;AAGpC,IAAA,IAAI,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,OAAO,GAAG,QAAQ,CAAA,CAAA;AACpC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAM,YAAA,GAAe,IAAI,eAAA,EAAgB;AACzC,MAAA,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM;AAC/C,QAAA,IAAI,UAAU,MAAA,EAAW;AACvB,UAAA,YAAA,CAAa,MAAA,CAAO,GAAA,EAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,QACxC;AAAA,MACF,CAAC,CAAA;AACD,MAAA,MAAM,WAAA,GAAc,aAAa,QAAA,EAAS;AAC1C,MAAA,IAAI,WAAA,EAAa;AACf,QAAA,GAAA,IAAO,IAAI,WAAW,CAAA,CAAA;AAAA,MACxB;AAAA,IACF;AAGA,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,cAAA,EAAgB,kBAAA;AAAA,MAChB,GAAG,IAAA,CAAK,OAAA;AAAA,MACR,GAAK,YAAA,CAAa,OAAA,IAAsC;AAAC,KAC3D;AAGA,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,YAAY,UAAA,CAAW,MAAM,WAAW,KAAA,EAAM,EAAG,KAAK,OAAO,CAAA;AAEnE,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,QAChC,GAAG,YAAA;AAAA,QACH,OAAA;AAAA,QACA,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AAED,MAAA,YAAA,CAAa,SAAS,CAAA;AAEtB,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,MAAM,IAAA,CAAK,WAAA,CAAY,QAAQ,CAAA;AAAA,MACvC;AAEA,MAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AAEjC,MAAA,OAAO;AAAA,QACL,IAAA;AAAA,QACA,QAAQ,QAAA,CAAS,MAAA;AAAA,QACjB,SAAS,QAAA,CAAS;AAAA,OACpB;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,YAAA,CAAa,SAAS,CAAA;AACtB,MAAA,MAAM,IAAA,CAAK,eAAe,KAAc,CAAA;AAAA,IAC1C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,GAAA,CAAO,QAAA,EAAkB,OAAA,EAAmD;AAC1F,IAAA,OAAO,IAAA,CAAK,QAAW,QAAA,EAAU,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,OAAO,CAAA;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,IAAA,CACd,QAAA,EACA,IAAA,EACA,OAAA,EACyB;AACzB,IAAA,OAAO,IAAA,CAAK,QAAW,QAAA,EAAU;AAAA,MAC/B,GAAG,OAAA;AAAA,MACH,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,GAAI;AAAA,KACrC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,GAAA,CACd,QAAA,EACA,IAAA,EACA,OAAA,EACyB;AACzB,IAAA,OAAO,IAAA,CAAK,QAAW,QAAA,EAAU;AAAA,MAC/B,GAAG,OAAA;AAAA,MACH,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,GAAI;AAAA,KACrC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,MAAA,CAAU,QAAA,EAAkB,OAAA,EAAmD;AAC7F,IAAA,OAAO,IAAA,CAAK,QAAW,QAAA,EAAU,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,UAAU,CAAA;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,YAAY,QAAA,EAAuC;AAC/D,IAAA,IAAI,UAAU,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA,CAAA;AAC7D,IAAA,IAAI,OAAA;AAEJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,MAAM,SAAS,IAAA,EAAK;AAC9B,MAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,QAAA,OAAA,GAAU,OAAA,CAAQ,OAAA;AAAA,MACpB,CAAA,MAAA,IAAW,QAAQ,KAAA,EAAO;AACxB,QAAA,OAAA,GAAU,OAAA,CAAQ,KAAA;AAAA,MACpB;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,OAAO;AAAA,MACL,OAAA;AAAA,MACA,QAAQ,QAAA,CAAS,MAAA;AAAA,MACjB;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,KAAA,EAAwB;AAC7C,IAAA,IAAI,KAAA,CAAM,SAAS,YAAA,EAAc;AAC/B,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,iBAAA;AAAA,QACT,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AAEA,IAAA,IAAI,YAAY,KAAA,EAAO;AACrB,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,MAAM,OAAA,IAAW,eAAA;AAAA,MAC1B,IAAA,EAAM;AAAA,KACR;AAAA,EACF;AACF;;;AChLO,IAAM,UAAA,GAAN,cAAyB,SAAA,CAAU;AAAA,EAIxC,WAAA,CAAY,SAAiB,MAAA,EAAoB;AAC/C,IAAA,KAAA,CAAM,EAAE,SAAS,CAAA;AACjB,IAAA,IAAA,CAAK,QAAQ,MAAA,CAAO,KAAA;AACpB,IAAA,IAAA,CAAK,SAAS,MAAA,CAAO,MAAA;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,WAAA,EAAgE;AAC1E,IAAA,OAAO,IAAA,CAAK,IAAA,CAAoB,QAAA,EAAU,WAAA,EAAa;AAAA,MACrD,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,UAAU,IAAA,CAAK,KAAA;AAAA,QACf,WAAW,IAAA,CAAK;AAAA;AAClB,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,MAAA,EAA6B;AACzC,IAAA,IAAI,MAAA,CAAO,KAAA,EAAO,IAAA,CAAK,KAAA,GAAQ,MAAA,CAAO,KAAA;AACtC,IAAA,IAAI,MAAA,CAAO,MAAA,EAAQ,IAAA,CAAK,MAAA,GAAS,MAAA,CAAO,MAAA;AAAA,EAC1C;AACF;AAKO,SAAS,gBAAA,CAAiB,SAAiB,MAAA,EAAoB;AACpE,EAAA,OAAO,IAAI,UAAA,CAAW,OAAA,EAAS,MAAM,CAAA;AACvC;AC1BA,IAAM,gBAAA,GAAmBA,oBAAiD,MAAS,CAAA;AAK5E,SAAS,iBAAA,CAAkB;AAAA,EAChC,QAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAA,EAA2B;AACzB,EAAA,MAAM,UAAA,GAAaC,cAAQ,MAAM;AAC/B,IAAA,IAAI,eAAe,UAAA,EAAY;AAC7B,MAAA,OAAO,IAAI,UAAA,CAAW,WAAA,EAAa,UAAU,CAAA;AAAA,IAC/C;AACA,IAAA,OAAO,IAAA;AAAA,EACT,GAAG,CAAC,WAAA,EAAa,YAAY,KAAA,EAAO,UAAA,EAAY,MAAM,CAAC,CAAA;AAEvD,EAAA,MAAM,KAAA,GAAQA,aAAA;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,KACF,CAAA;AAAA,IACA,CAAC,UAAU;AAAA,GACb;AAEA,EAAA,uBAAOC,cAAA,CAAC,gBAAA,CAAiB,QAAA,EAAjB,EAA0B,OAAe,QAAA,EAAS,CAAA;AAC5D;AAKO,SAAS,mBAAA,GAAsB;AACpC,EAAA,MAAM,OAAA,GAAUC,iBAAW,gBAAgB,CAAA;AAC3C,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,MAAM,IAAI,MAAM,8DAA8D,CAAA;AAAA,EAChF;AACA,EAAA,OAAO,OAAA;AACT;ACpCA,IAAM,WAAA,GAAcH,oBAA4C,MAAS,CAAA;AAKlE,SAAS,YAAA,CAAa,EAAE,QAAA,EAAU,OAAA,EAAS,QAAO,EAAsB;AAC7E,EAAA,MAAM,MAAA,GAASC,cAAQ,MAAM;AAC3B,IAAA,OAAO,IAAI,UAAA,CAAW,OAAA,EAAS,MAAM,CAAA;AAAA,EACvC,GAAG,CAAC,OAAA,EAAS,OAAO,KAAA,EAAO,MAAA,CAAO,MAAM,CAAC,CAAA;AAEzC,EAAA,MAAM,KAAA,GAAQA,cAAQ,OAAO,EAAE,QAAO,CAAA,EAAI,CAAC,MAAM,CAAC,CAAA;AAElD,EAAA,uBAAOC,cAAAA,CAAC,WAAA,CAAY,QAAA,EAAZ,EAAqB,OAAe,QAAA,EAAS,CAAA;AACvD;AAKO,SAAS,cAAA,GAAiB;AAC/B,EAAA,MAAM,OAAA,GAAUC,iBAAW,WAAW,CAAA;AACtC,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,EACrE;AACA,EAAA,OAAO,OAAA,CAAQ,MAAA;AACjB;;;ACjCO,SAAS,aAAA,GAAgB;AAE9B,EAAA,IAAI;AACF,IAAA,OAAO,cAAA,EAAe;AAAA,EACxB,CAAA,CAAA,MAAQ;AAEN,IAAA,MAAM,UAAU,mBAAA,EAAoB;AACpC,IAAA,IAAI,CAAC,QAAQ,UAAA,EAAY;AACvB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,OAAO,OAAA,CAAQ,UAAA;AAAA,EACjB;AACF;ACbO,SAAS,QAAA,GAAW;AACzB,EAAA,MAAM,SAAS,aAAA,EAAc;AAE7B,EAAA,OAAOC,sBAAA,CAAY;AAAA,IACjB,UAAA,EAAY,OAAO,WAAA,KAA8B;AAC/C,MAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,KAAA,CAAM,WAAW,CAAA;AAC/C,MAAA,OAAO,QAAA,CAAS,IAAA;AAAA,IAClB;AAAA,GACD,CAAA;AACH","file":"index.js","sourcesContent":["/**\n * Core API Client\n * Base class for making HTTP requests\n */\n\nimport { ApiClientConfig, RequestOptions, ApiResponse, ApiError } from './types';\n\nexport class ApiClient {\n protected baseUrl: string;\n protected headers: Record<string, string>;\n protected timeout: number;\n\n constructor(config: ApiClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.headers = config.headers || {};\n this.timeout = config.timeout || 30000;\n }\n\n /**\n * Update client configuration\n */\n setConfig(config: Partial<ApiClientConfig>) {\n if (config.baseUrl) this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n if (config.headers) this.headers = { ...this.headers, ...config.headers };\n if (config.timeout) this.timeout = config.timeout;\n }\n\n /**\n * Set authorization token\n */\n setAuthToken(token: string) {\n this.headers['Authorization'] = `Bearer ${token}`;\n }\n\n /**\n * Make an HTTP request\n */\n protected async request<T>(\n endpoint: string,\n options: RequestOptions = {}\n ): Promise<ApiResponse<T>> {\n const { params, ...fetchOptions } = options;\n\n // Build URL with query parameters\n let url = `${this.baseUrl}${endpoint}`;\n if (params) {\n const searchParams = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined) {\n searchParams.append(key, String(value));\n }\n });\n const queryString = searchParams.toString();\n if (queryString) {\n url += `?${queryString}`;\n }\n }\n\n // Merge headers\n const headers = {\n 'Content-Type': 'application/json',\n ...this.headers,\n ...((fetchOptions.headers as Record<string, string>) || {}),\n };\n\n // Create abort controller for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n ...fetchOptions,\n headers,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw await this.handleError(response);\n }\n\n const data = await response.json();\n\n return {\n data,\n status: response.status,\n headers: response.headers,\n };\n } catch (error) {\n clearTimeout(timeoutId);\n throw this.normalizeError(error as Error);\n }\n }\n\n /**\n * GET request\n */\n protected async get<T>(endpoint: string, options?: RequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: 'GET' });\n }\n\n /**\n * POST request\n */\n protected async post<T>(\n endpoint: string,\n body?: any,\n options?: RequestOptions\n ): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, {\n ...options,\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n /**\n * PUT request\n */\n protected async put<T>(\n endpoint: string,\n body?: any,\n options?: RequestOptions\n ): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, {\n ...options,\n method: 'PUT',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n /**\n * DELETE request\n */\n protected async delete<T>(endpoint: string, options?: RequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: 'DELETE' });\n }\n\n /**\n * Handle error responses\n */\n private async handleError(response: Response): Promise<ApiError> {\n let message = `HTTP ${response.status}: ${response.statusText}`;\n let details: any;\n\n try {\n details = await response.json();\n if (details.message) {\n message = details.message;\n } else if (details.error) {\n message = details.error;\n }\n } catch {\n // Response body is not JSON\n }\n\n return {\n message,\n status: response.status,\n details,\n };\n }\n\n /**\n * Normalize errors to consistent format\n */\n private normalizeError(error: Error): ApiError {\n if (error.name === 'AbortError') {\n return {\n message: 'Request timeout',\n code: 'TIMEOUT',\n };\n }\n\n if ('status' in error) {\n return error as ApiError;\n }\n\n return {\n message: error.message || 'Unknown error',\n code: 'UNKNOWN',\n };\n }\n}\n","/**\n * JRNI API Client\n * Provides methods for interacting with the JRNI API\n */\n\nimport { ApiClient } from './core';\nimport { LoginRequest, LoginResponse, ApiResponse, JrniConfig } from './types';\n\nexport class JrniClient extends ApiClient {\n private appId: string;\n private appKey: string;\n\n constructor(baseUrl: string, config: JrniConfig) {\n super({ baseUrl });\n this.appId = config.appId;\n this.appKey = config.appKey;\n }\n\n /**\n * Login to JRNI\n */\n async login(credentials: LoginRequest): Promise<ApiResponse<LoginResponse>> {\n return this.post<LoginResponse>('/login', credentials, {\n headers: {\n 'Content-Type': 'application/json',\n 'App-Id': this.appId,\n 'App-Key': this.appKey,\n },\n });\n }\n\n /**\n * Update JRNI configuration\n */\n setJrniConfig(config: Partial<JrniConfig>) {\n if (config.appId) this.appId = config.appId;\n if (config.appKey) this.appKey = config.appKey;\n }\n}\n\n/**\n * Create a new JRNI client instance\n */\nexport function createJrniClient(baseUrl: string, config: JrniConfig) {\n return new JrniClient(baseUrl, config);\n}\n","/**\n * React Context Provider for API Clients\n * Combined provider for applications using multiple API clients\n */\n\nimport React, { createContext, useContext, useMemo, ReactNode } from 'react';\nimport { JrniClient } from '../jrni';\nimport { JrniConfig } from '../types';\n\ninterface ApiClientContextValue {\n jrniClient: JrniClient | null;\n}\n\ninterface ApiClientProviderProps {\n children: ReactNode;\n jrniBaseUrl?: string;\n jrniConfig?: JrniConfig;\n}\n\nconst ApiClientContext = createContext<ApiClientContextValue | undefined>(undefined);\n\n/**\n * Combined provider for multiple API clients\n */\nexport function ApiClientProvider({\n children,\n jrniBaseUrl,\n jrniConfig,\n}: ApiClientProviderProps) {\n const jrniClient = useMemo(() => {\n if (jrniBaseUrl && jrniConfig) {\n return new JrniClient(jrniBaseUrl, jrniConfig);\n }\n return null;\n }, [jrniBaseUrl, jrniConfig?.appId, jrniConfig?.appKey]);\n\n const value = useMemo(\n () => ({\n jrniClient,\n }),\n [jrniClient]\n );\n\n return <ApiClientContext.Provider value={value}>{children}</ApiClientContext.Provider>;\n}\n\n/**\n * Hook to access API client context\n */\nexport function useApiClientContext() {\n const context = useContext(ApiClientContext);\n if (context === undefined) {\n throw new Error('useApiClientContext must be used within an ApiClientProvider');\n }\n return context;\n}\n","/**\n * React Context Provider for JRNI API Client\n * Standalone provider for apps that only use JRNI\n */\n\nimport React, { createContext, useContext, useMemo, ReactNode } from 'react';\nimport { JrniClient } from '../jrni';\nimport { JrniConfig } from '../types';\n\ninterface JrniContextValue {\n client: JrniClient;\n}\n\ninterface JrniProviderProps {\n children: ReactNode;\n baseUrl: string;\n config: JrniConfig;\n}\n\nconst JrniContext = createContext<JrniContextValue | undefined>(undefined);\n\n/**\n * Provider component for JRNI client\n */\nexport function JrniProvider({ children, baseUrl, config }: JrniProviderProps) {\n const client = useMemo(() => {\n return new JrniClient(baseUrl, config);\n }, [baseUrl, config.appId, config.appKey]);\n\n const value = useMemo(() => ({ client }), [client]);\n\n return <JrniContext.Provider value={value}>{children}</JrniContext.Provider>;\n}\n\n/**\n * Hook to access JRNI client from context\n */\nexport function useJrniContext() {\n const context = useContext(JrniContext);\n if (context === undefined) {\n throw new Error('useJrniContext must be used within a JrniProvider');\n }\n return context.client;\n}\n","/**\n * Hook to access API clients from context\n */\n\nimport { useApiClientContext } from '../providers/ApiClientProvider';\nimport { useJrniContext } from '../providers/JrniProvider';\n\n/**\n * Hook to get JRNI client from either ApiClientProvider or JrniProvider\n */\nexport function useJrniClient() {\n // Try to get from standalone provider first\n try {\n return useJrniContext();\n } catch {\n // Fall back to combined provider\n const context = useApiClientContext();\n if (!context.jrniClient) {\n throw new Error(\n 'JRNI client not configured. Wrap your app with ApiClientProvider or JrniProvider.'\n );\n }\n return context.jrniClient;\n }\n}\n","/**\n * React hooks for JRNI API\n */\n\nimport { useMutation } from '@tanstack/react-query';\nimport { useJrniClient } from './useApiClient';\nimport { LoginRequest, LoginResponse } from '../types';\n\n/**\n * Hook for JRNI login\n */\nexport function useLogin() {\n const client = useJrniClient();\n\n return useMutation({\n mutationFn: async (credentials: LoginRequest) => {\n const response = await client.login(credentials);\n return response.data;\n },\n });\n}\n"]}
1
+ {"version":3,"sources":["../src/core.ts","../src/booking-lab.ts","../src/jrni.ts","../src/providers/ApiClientProvider.tsx","../src/providers/BookingLabProvider.tsx","../src/providers/JrniProvider.tsx","../src/hooks/useApiClient.ts","../src/hooks/useJrni.ts","../src/hooks/useBookingLab.ts"],"names":["createContext","QueryClient","useMemo","jsx","QueryClientProvider","useContext","useMutation","useQuery","useQueryClient"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Core API Client\n * Base class for making HTTP requests\n */\n\nimport { ApiClientConfig, RequestOptions, ApiResponse, ApiError } from './types';\n\nexport class ApiClient {\n protected baseUrl: string;\n protected headers: Record<string, string>;\n protected timeout: number;\n\n constructor(config: ApiClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.headers = config.headers || {};\n this.timeout = config.timeout || 30000;\n }\n\n /**\n * Update client configuration\n */\n setConfig(config: Partial<ApiClientConfig>) {\n if (config.baseUrl) this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n if (config.headers) this.headers = { ...this.headers, ...config.headers };\n if (config.timeout) this.timeout = config.timeout;\n }\n\n /**\n * Set authorization token\n */\n setAuthToken(token: string) {\n this.headers['Authorization'] = `Bearer ${token}`;\n }\n\n /**\n * Make an HTTP request\n */\n protected async request<T>(\n endpoint: string,\n options: RequestOptions = {}\n ): Promise<ApiResponse<T>> {\n const { params, ...fetchOptions } = options;\n\n // Build URL with query parameters\n let url = `${this.baseUrl}${endpoint}`;\n if (params) {\n const searchParams = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined) {\n searchParams.append(key, String(value));\n }\n });\n const queryString = searchParams.toString();\n if (queryString) {\n url += `?${queryString}`;\n }\n }\n\n // Merge headers\n const headers = {\n 'Content-Type': 'application/json',\n ...this.headers,\n ...((fetchOptions.headers as Record<string, string>) || {}),\n };\n\n // Create abort controller for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n ...fetchOptions,\n headers,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw await this.handleError(response);\n }\n\n const data = await response.json();\n\n return {\n data,\n status: response.status,\n headers: response.headers,\n };\n } catch (error) {\n clearTimeout(timeoutId);\n throw this.normalizeError(error as Error);\n }\n }\n\n /**\n * GET request\n */\n protected async get<T>(endpoint: string, options?: RequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: 'GET' });\n }\n\n /**\n * POST request\n */\n protected async post<T>(\n endpoint: string,\n body?: any,\n options?: RequestOptions\n ): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, {\n ...options,\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n /**\n * PUT request\n */\n protected async put<T>(\n endpoint: string,\n body?: any,\n options?: RequestOptions\n ): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, {\n ...options,\n method: 'PUT',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n /**\n * DELETE request\n */\n protected async delete<T>(endpoint: string, options?: RequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: 'DELETE' });\n }\n\n /**\n * Handle error responses\n */\n private async handleError(response: Response): Promise<ApiError> {\n let message = `HTTP ${response.status}: ${response.statusText}`;\n let details: any;\n\n try {\n details = await response.json();\n if (details.message) {\n message = details.message;\n } else if (details.error) {\n message = details.error;\n }\n } catch {\n // Response body is not JSON\n }\n\n return {\n message,\n status: response.status,\n details,\n };\n }\n\n /**\n * Normalize errors to consistent format\n */\n private normalizeError(error: Error): ApiError {\n if (error.name === 'AbortError') {\n return {\n message: 'Request timeout',\n code: 'TIMEOUT',\n };\n }\n\n if ('status' in error) {\n return error as ApiError;\n }\n\n return {\n message: error.message || 'Unknown error',\n code: 'UNKNOWN',\n };\n }\n}\n","/**\n * BookingLab API Client\n * Provides methods for interacting with the BookingLab API\n */\n\nimport { ApiClient } from './core';\nimport { Booking, CreateBookingRequest, Service, ApiResponse } from './types';\n\nexport class BookingLabClient extends ApiClient {\n /**\n * Get all bookings\n */\n async getBookings(userId?: string): Promise<ApiResponse<Booking[]>> {\n return this.get<Booking[]>('/bookings', {\n params: userId ? { userId } : undefined,\n });\n }\n\n /**\n * Get a single booking by ID\n */\n async getBooking(bookingId: string): Promise<ApiResponse<Booking>> {\n return this.get<Booking>(`/bookings/${bookingId}`);\n }\n\n /**\n * Create a new booking\n */\n async createBooking(booking: CreateBookingRequest): Promise<ApiResponse<Booking>> {\n return this.post<Booking>('/bookings', booking);\n }\n\n /**\n * Update an existing booking\n */\n async updateBooking(\n bookingId: string,\n updates: Partial<Booking>\n ): Promise<ApiResponse<Booking>> {\n return this.put<Booking>(`/bookings/${bookingId}`, updates);\n }\n\n /**\n * Cancel a booking\n */\n async cancelBooking(bookingId: string): Promise<ApiResponse<Booking>> {\n return this.put<Booking>(`/bookings/${bookingId}`, { status: 'cancelled' });\n }\n\n /**\n * Delete a booking\n */\n async deleteBooking(bookingId: string): Promise<ApiResponse<void>> {\n return this.delete<void>(`/bookings/${bookingId}`);\n }\n\n /**\n * Get all services\n */\n async getServices(): Promise<ApiResponse<Service[]>> {\n return this.get<Service[]>('/services');\n }\n\n /**\n * Get a single service by ID\n */\n async getService(serviceId: string): Promise<ApiResponse<Service>> {\n return this.get<Service>(`/services/${serviceId}`);\n }\n}\n\n/**\n * Create a new BookingLab client instance\n */\nexport function createBookingLabClient(baseUrl: string, authToken?: string) {\n const client = new BookingLabClient({ baseUrl });\n if (authToken) {\n client.setAuthToken(authToken);\n }\n return client;\n}\n","/**\n * JRNI API Client\n * Provides methods for interacting with the JRNI API\n */\n\nimport { ApiClient } from './core';\nimport { LoginRequest, LoginResponse, ApiResponse, JrniConfig } from './types';\n\nexport class JrniClient extends ApiClient {\n private appId: string;\n private appKey: string;\n\n constructor(baseUrl: string, config: JrniConfig) {\n super({ baseUrl });\n this.appId = config.appId;\n this.appKey = config.appKey;\n }\n\n /**\n * Login to JRNI\n */\n async login(credentials: LoginRequest): Promise<ApiResponse<LoginResponse>> {\n return this.post<LoginResponse>('/login', credentials, {\n headers: {\n 'Content-Type': 'application/json',\n 'App-Id': this.appId,\n 'App-Key': this.appKey,\n },\n });\n }\n\n /**\n * Update JRNI configuration\n */\n setJrniConfig(config: Partial<JrniConfig>) {\n if (config.appId) this.appId = config.appId;\n if (config.appKey) this.appKey = config.appKey;\n }\n}\n\n/**\n * Create a new JRNI client instance\n */\nexport function createJrniClient(baseUrl: string, config: JrniConfig) {\n return new JrniClient(baseUrl, config);\n}\n","/**\n * React Context Provider for API Clients\n * Combined provider for applications using multiple API clients\n */\n\nimport React, { createContext, useContext, useMemo, ReactNode } from 'react';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { BookingLabClient } from '../booking-lab';\nimport { JrniClient } from '../jrni';\nimport { JrniConfig } from '../types';\n\ninterface ApiClientContextValue {\n bookingLabClient: BookingLabClient | null;\n jrniClient: JrniClient | null;\n}\n\ninterface ApiClientProviderProps {\n children: ReactNode;\n bookingLabBaseUrl?: string;\n jrniBaseUrl?: string;\n jrniConfig?: JrniConfig;\n authToken?: string;\n queryClient?: QueryClient;\n}\n\nconst ApiClientContext = createContext<ApiClientContextValue | undefined>(undefined);\n\n// Default QueryClient for the provider\nconst defaultQueryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 5 * 60 * 1000,\n retry: 1,\n },\n },\n});\n\n/**\n * Combined provider for multiple API clients\n * Includes QueryClientProvider for React Query hooks\n */\nexport function ApiClientProvider({\n children,\n bookingLabBaseUrl,\n jrniBaseUrl,\n jrniConfig,\n authToken,\n queryClient,\n}: ApiClientProviderProps) {\n const client = queryClient || defaultQueryClient;\n\n const bookingLabClient = useMemo(() => {\n if (!bookingLabBaseUrl) return null;\n const clientInstance = new BookingLabClient({ baseUrl: bookingLabBaseUrl });\n if (authToken) {\n clientInstance.setAuthToken(authToken);\n }\n return clientInstance;\n }, [bookingLabBaseUrl, authToken]);\n\n const jrniClient = useMemo(() => {\n if (jrniBaseUrl && jrniConfig) {\n return new JrniClient(jrniBaseUrl, jrniConfig);\n }\n return null;\n }, [jrniBaseUrl, jrniConfig?.appId, jrniConfig?.appKey]);\n\n const value = useMemo(\n () => ({\n bookingLabClient,\n jrniClient,\n }),\n [bookingLabClient, jrniClient]\n );\n\n return (\n <QueryClientProvider client={client}>\n <ApiClientContext.Provider value={value}>{children}</ApiClientContext.Provider>\n </QueryClientProvider>\n );\n}\n\n/**\n * Hook to access API client context\n */\nexport function useApiClientContext() {\n const context = useContext(ApiClientContext);\n if (context === undefined) {\n throw new Error('useApiClientContext must be used within an ApiClientProvider');\n }\n return context;\n}\n","/**\n * React Context Provider for BookingLab API Client\n * Standalone provider for apps that only use BookingLab\n */\n\nimport React, { createContext, useContext, useMemo, ReactNode } from 'react';\nimport { BookingLabClient } from '../booking-lab';\n\ninterface BookingLabContextValue {\n client: BookingLabClient;\n}\n\ninterface BookingLabProviderProps {\n children: ReactNode;\n baseUrl: string;\n authToken?: string;\n}\n\nconst BookingLabContext = createContext<BookingLabContextValue | undefined>(undefined);\n\n/**\n * Provider component for BookingLab client\n */\nexport function BookingLabProvider({\n children,\n baseUrl,\n authToken,\n}: BookingLabProviderProps) {\n const client = useMemo(() => {\n const clientInstance = new BookingLabClient({ baseUrl });\n if (authToken) {\n clientInstance.setAuthToken(authToken);\n }\n return clientInstance;\n }, [baseUrl, authToken]);\n\n const value = useMemo(() => ({ client }), [client]);\n\n return (\n <BookingLabContext.Provider value={value}>\n {children}\n </BookingLabContext.Provider>\n );\n}\n\n/**\n * Hook to access BookingLab client from context\n */\nexport function useBookingLabContext() {\n const context = useContext(BookingLabContext);\n if (context === undefined) {\n throw new Error('useBookingLabContext must be used within a BookingLabProvider');\n }\n return context.client;\n}\n","/**\n * React Context Provider for JRNI API Client\n * Standalone provider for apps that only use JRNI\n */\n\nimport React, { createContext, useContext, useMemo, ReactNode } from 'react';\nimport { JrniClient } from '../jrni';\nimport { JrniConfig } from '../types';\n\ninterface JrniContextValue {\n client: JrniClient;\n}\n\ninterface JrniProviderProps {\n children: ReactNode;\n baseUrl: string;\n config: JrniConfig;\n}\n\nconst JrniContext = createContext<JrniContextValue | undefined>(undefined);\n\n/**\n * Provider component for JRNI client\n */\nexport function JrniProvider({ children, baseUrl, config }: JrniProviderProps) {\n const client = useMemo(() => {\n return new JrniClient(baseUrl, config);\n }, [baseUrl, config.appId, config.appKey]);\n\n const value = useMemo(() => ({ client }), [client]);\n\n return <JrniContext.Provider value={value}>{children}</JrniContext.Provider>;\n}\n\n/**\n * Hook to access JRNI client from context\n */\nexport function useJrniContext() {\n const context = useContext(JrniContext);\n if (context === undefined) {\n throw new Error('useJrniContext must be used within a JrniProvider');\n }\n return context.client;\n}\n","/**\n * Hook to access API clients from context\n */\n\nimport { useApiClientContext } from '../providers/ApiClientProvider';\nimport { useBookingLabContext } from '../providers/BookingLabProvider';\nimport { useJrniContext } from '../providers/JrniProvider';\n\n/**\n * Hook to get BookingLab client from either ApiClientProvider or BookingLabProvider\n */\nexport function useBookingLabClient() {\n // Try to get from standalone provider first\n try {\n return useBookingLabContext();\n } catch {\n // Fall back to combined provider\n const context = useApiClientContext();\n if (!context.bookingLabClient) {\n throw new Error(\n 'BookingLab client not configured. Wrap your app with ApiClientProvider or BookingLabProvider.'\n );\n }\n return context.bookingLabClient;\n }\n}\n\n/**\n * Hook to get JRNI client from either ApiClientProvider or JrniProvider\n */\nexport function useJrniClient() {\n // Try to get from standalone provider first\n try {\n return useJrniContext();\n } catch {\n // Fall back to combined provider\n const context = useApiClientContext();\n if (!context.jrniClient) {\n throw new Error(\n 'JRNI client not configured. Wrap your app with ApiClientProvider or JrniProvider.'\n );\n }\n return context.jrniClient;\n }\n}\n","/**\n * React hooks for JRNI API\n */\n\nimport { useMutation } from '@tanstack/react-query';\nimport { useJrniClient } from './useApiClient';\nimport { LoginRequest, LoginResponse } from '../types';\n\n/**\n * Hook for JRNI login\n */\nexport function useLogin() {\n const client = useJrniClient();\n\n return useMutation({\n mutationFn: async (credentials: LoginRequest) => {\n const response = await client.login(credentials);\n return response.data;\n },\n });\n}\n","/**\n * React hooks for BookingLab API\n */\n\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { Booking, CreateBookingRequest, Service } from '../types';\nimport { useBookingLabClient } from './useApiClient';\n\n/**\n * Hook to fetch bookings\n */\nexport function useBookings(userId?: string) {\n const client = useBookingLabClient();\n \n return useQuery({\n queryKey: ['bookings', userId],\n queryFn: async () => {\n const response = await client.getBookings(userId);\n return response.data;\n },\n });\n}\n\n/**\n * Hook to fetch a single booking\n */\nexport function useBooking(bookingId: string) {\n const client = useBookingLabClient();\n \n return useQuery({\n queryKey: ['booking', bookingId],\n queryFn: async () => {\n const response = await client.getBooking(bookingId);\n return response.data;\n },\n enabled: !!bookingId,\n });\n}\n\n/**\n * Hook to create a booking\n */\nexport function useCreateBooking() {\n const client = useBookingLabClient();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async (booking: CreateBookingRequest) => {\n const response = await client.createBooking(booking);\n return response.data;\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['bookings'] });\n },\n });\n}\n\n/**\n * Hook to update a booking\n */\nexport function useUpdateBooking() {\n const client = useBookingLabClient();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ id, updates }: { id: string; updates: Partial<Booking> }) => {\n const response = await client.updateBooking(id, updates);\n return response.data;\n },\n onSuccess: (_, variables) => {\n queryClient.invalidateQueries({ queryKey: ['bookings'] });\n queryClient.invalidateQueries({ queryKey: ['booking', variables.id] });\n },\n });\n}\n\n/**\n * Hook to cancel a booking\n */\nexport function useCancelBooking() {\n const client = useBookingLabClient();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async (bookingId: string) => {\n const response = await client.cancelBooking(bookingId);\n return response.data;\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['bookings'] });\n },\n });\n}\n\n/**\n * Hook to fetch services\n */\nexport function useServices() {\n const client = useBookingLabClient();\n \n return useQuery({\n queryKey: ['services'],\n queryFn: async () => {\n const response = await client.getServices();\n return response.data;\n },\n });\n}\n\n/**\n * Hook to fetch a single service\n */\nexport function useService(serviceId: string) {\n const client = useBookingLabClient();\n \n return useQuery({\n queryKey: ['service', serviceId],\n queryFn: async () => {\n const response = await client.getService(serviceId);\n return response.data;\n },\n enabled: !!serviceId,\n });\n}\n"]}
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createContext, useMemo, useContext } from 'react';
2
+ import { QueryClient, QueryClientProvider, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
2
3
  import { jsx } from 'react/jsx-runtime';
3
- import { useMutation } from '@tanstack/react-query';
4
4
 
5
5
  // src/core.ts
6
6
  var ApiClient = class {
@@ -142,6 +142,67 @@ var ApiClient = class {
142
142
  }
143
143
  };
144
144
 
145
+ // src/booking-lab.ts
146
+ var BookingLabClient = class extends ApiClient {
147
+ /**
148
+ * Get all bookings
149
+ */
150
+ async getBookings(userId) {
151
+ return this.get("/bookings", {
152
+ params: userId ? { userId } : void 0
153
+ });
154
+ }
155
+ /**
156
+ * Get a single booking by ID
157
+ */
158
+ async getBooking(bookingId) {
159
+ return this.get(`/bookings/${bookingId}`);
160
+ }
161
+ /**
162
+ * Create a new booking
163
+ */
164
+ async createBooking(booking) {
165
+ return this.post("/bookings", booking);
166
+ }
167
+ /**
168
+ * Update an existing booking
169
+ */
170
+ async updateBooking(bookingId, updates) {
171
+ return this.put(`/bookings/${bookingId}`, updates);
172
+ }
173
+ /**
174
+ * Cancel a booking
175
+ */
176
+ async cancelBooking(bookingId) {
177
+ return this.put(`/bookings/${bookingId}`, { status: "cancelled" });
178
+ }
179
+ /**
180
+ * Delete a booking
181
+ */
182
+ async deleteBooking(bookingId) {
183
+ return this.delete(`/bookings/${bookingId}`);
184
+ }
185
+ /**
186
+ * Get all services
187
+ */
188
+ async getServices() {
189
+ return this.get("/services");
190
+ }
191
+ /**
192
+ * Get a single service by ID
193
+ */
194
+ async getService(serviceId) {
195
+ return this.get(`/services/${serviceId}`);
196
+ }
197
+ };
198
+ function createBookingLabClient(baseUrl, authToken) {
199
+ const client = new BookingLabClient({ baseUrl });
200
+ if (authToken) {
201
+ client.setAuthToken(authToken);
202
+ }
203
+ return client;
204
+ }
205
+
145
206
  // src/jrni.ts
146
207
  var JrniClient = class extends ApiClient {
147
208
  constructor(baseUrl, config) {
@@ -173,11 +234,31 @@ function createJrniClient(baseUrl, config) {
173
234
  return new JrniClient(baseUrl, config);
174
235
  }
175
236
  var ApiClientContext = createContext(void 0);
237
+ var defaultQueryClient = new QueryClient({
238
+ defaultOptions: {
239
+ queries: {
240
+ staleTime: 5 * 60 * 1e3,
241
+ retry: 1
242
+ }
243
+ }
244
+ });
176
245
  function ApiClientProvider({
177
246
  children,
247
+ bookingLabBaseUrl,
178
248
  jrniBaseUrl,
179
- jrniConfig
249
+ jrniConfig,
250
+ authToken,
251
+ queryClient
180
252
  }) {
253
+ const client = queryClient || defaultQueryClient;
254
+ const bookingLabClient = useMemo(() => {
255
+ if (!bookingLabBaseUrl) return null;
256
+ const clientInstance = new BookingLabClient({ baseUrl: bookingLabBaseUrl });
257
+ if (authToken) {
258
+ clientInstance.setAuthToken(authToken);
259
+ }
260
+ return clientInstance;
261
+ }, [bookingLabBaseUrl, authToken]);
181
262
  const jrniClient = useMemo(() => {
182
263
  if (jrniBaseUrl && jrniConfig) {
183
264
  return new JrniClient(jrniBaseUrl, jrniConfig);
@@ -186,11 +267,12 @@ function ApiClientProvider({
186
267
  }, [jrniBaseUrl, jrniConfig?.appId, jrniConfig?.appKey]);
187
268
  const value = useMemo(
188
269
  () => ({
270
+ bookingLabClient,
189
271
  jrniClient
190
272
  }),
191
- [jrniClient]
273
+ [bookingLabClient, jrniClient]
192
274
  );
193
- return /* @__PURE__ */ jsx(ApiClientContext.Provider, { value, children });
275
+ return /* @__PURE__ */ jsx(QueryClientProvider, { client, children: /* @__PURE__ */ jsx(ApiClientContext.Provider, { value, children }) });
194
276
  }
195
277
  function useApiClientContext() {
196
278
  const context = useContext(ApiClientContext);
@@ -199,6 +281,29 @@ function useApiClientContext() {
199
281
  }
200
282
  return context;
201
283
  }
284
+ var BookingLabContext = createContext(void 0);
285
+ function BookingLabProvider({
286
+ children,
287
+ baseUrl,
288
+ authToken
289
+ }) {
290
+ const client = useMemo(() => {
291
+ const clientInstance = new BookingLabClient({ baseUrl });
292
+ if (authToken) {
293
+ clientInstance.setAuthToken(authToken);
294
+ }
295
+ return clientInstance;
296
+ }, [baseUrl, authToken]);
297
+ const value = useMemo(() => ({ client }), [client]);
298
+ return /* @__PURE__ */ jsx(BookingLabContext.Provider, { value, children });
299
+ }
300
+ function useBookingLabContext() {
301
+ const context = useContext(BookingLabContext);
302
+ if (context === void 0) {
303
+ throw new Error("useBookingLabContext must be used within a BookingLabProvider");
304
+ }
305
+ return context.client;
306
+ }
202
307
  var JrniContext = createContext(void 0);
203
308
  function JrniProvider({ children, baseUrl, config }) {
204
309
  const client = useMemo(() => {
@@ -216,6 +321,19 @@ function useJrniContext() {
216
321
  }
217
322
 
218
323
  // src/hooks/useApiClient.ts
324
+ function useBookingLabClient() {
325
+ try {
326
+ return useBookingLabContext();
327
+ } catch {
328
+ const context = useApiClientContext();
329
+ if (!context.bookingLabClient) {
330
+ throw new Error(
331
+ "BookingLab client not configured. Wrap your app with ApiClientProvider or BookingLabProvider."
332
+ );
333
+ }
334
+ return context.bookingLabClient;
335
+ }
336
+ }
219
337
  function useJrniClient() {
220
338
  try {
221
339
  return useJrniContext();
@@ -238,7 +356,89 @@ function useLogin() {
238
356
  }
239
357
  });
240
358
  }
359
+ function useBookings(userId) {
360
+ const client = useBookingLabClient();
361
+ return useQuery({
362
+ queryKey: ["bookings", userId],
363
+ queryFn: async () => {
364
+ const response = await client.getBookings(userId);
365
+ return response.data;
366
+ }
367
+ });
368
+ }
369
+ function useBooking(bookingId) {
370
+ const client = useBookingLabClient();
371
+ return useQuery({
372
+ queryKey: ["booking", bookingId],
373
+ queryFn: async () => {
374
+ const response = await client.getBooking(bookingId);
375
+ return response.data;
376
+ },
377
+ enabled: !!bookingId
378
+ });
379
+ }
380
+ function useCreateBooking() {
381
+ const client = useBookingLabClient();
382
+ const queryClient = useQueryClient();
383
+ return useMutation({
384
+ mutationFn: async (booking) => {
385
+ const response = await client.createBooking(booking);
386
+ return response.data;
387
+ },
388
+ onSuccess: () => {
389
+ queryClient.invalidateQueries({ queryKey: ["bookings"] });
390
+ }
391
+ });
392
+ }
393
+ function useUpdateBooking() {
394
+ const client = useBookingLabClient();
395
+ const queryClient = useQueryClient();
396
+ return useMutation({
397
+ mutationFn: async ({ id, updates }) => {
398
+ const response = await client.updateBooking(id, updates);
399
+ return response.data;
400
+ },
401
+ onSuccess: (_, variables) => {
402
+ queryClient.invalidateQueries({ queryKey: ["bookings"] });
403
+ queryClient.invalidateQueries({ queryKey: ["booking", variables.id] });
404
+ }
405
+ });
406
+ }
407
+ function useCancelBooking() {
408
+ const client = useBookingLabClient();
409
+ const queryClient = useQueryClient();
410
+ return useMutation({
411
+ mutationFn: async (bookingId) => {
412
+ const response = await client.cancelBooking(bookingId);
413
+ return response.data;
414
+ },
415
+ onSuccess: () => {
416
+ queryClient.invalidateQueries({ queryKey: ["bookings"] });
417
+ }
418
+ });
419
+ }
420
+ function useServices() {
421
+ const client = useBookingLabClient();
422
+ return useQuery({
423
+ queryKey: ["services"],
424
+ queryFn: async () => {
425
+ const response = await client.getServices();
426
+ return response.data;
427
+ }
428
+ });
429
+ }
430
+ function useService(serviceId) {
431
+ const client = useBookingLabClient();
432
+ return useQuery({
433
+ queryKey: ["service", serviceId],
434
+ queryFn: async () => {
435
+ const response = await client.getService(serviceId);
436
+ return response.data;
437
+ },
438
+ enabled: !!serviceId
439
+ });
440
+ }
241
441
 
242
- export { ApiClient, ApiClientProvider, JrniClient, JrniProvider, createJrniClient, useApiClientContext, useJrniClient, useJrniContext, useLogin };
442
+ export { ApiClient, ApiClientProvider, BookingLabClient, BookingLabProvider, JrniClient, JrniProvider, createBookingLabClient, createJrniClient, useApiClientContext, useBooking, useBookingLabClient, useBookingLabContext, useBookings, useCancelBooking, useCreateBooking, useJrniClient, useJrniContext, useLogin, useService, useServices, useUpdateBooking };
243
443
  //# sourceMappingURL=index.mjs.map
244
444
  //# sourceMappingURL=index.mjs.map