@htlkg/data 0.0.19 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/client/index.d.ts +257 -1
  2. package/dist/client/index.js +59 -1
  3. package/dist/client/index.js.map +1 -1
  4. package/dist/common-DSxswsZ3.d.ts +40 -0
  5. package/dist/hooks/index.d.ts +162 -10
  6. package/dist/hooks/index.js +191 -33
  7. package/dist/hooks/index.js.map +1 -1
  8. package/dist/index.d.ts +9 -5
  9. package/dist/index.js +789 -13
  10. package/dist/index.js.map +1 -1
  11. package/dist/mutations/index.d.ts +342 -4
  12. package/dist/mutations/index.js +486 -0
  13. package/dist/mutations/index.js.map +1 -1
  14. package/dist/{productInstances-BA3cNsYc.d.ts → productInstances-BpQv1oLS.d.ts} +2 -40
  15. package/dist/queries/index.d.ts +113 -2
  16. package/dist/queries/index.js +192 -1
  17. package/dist/queries/index.js.map +1 -1
  18. package/dist/reservations-C0FNm__0.d.ts +154 -0
  19. package/dist/reservations-CdDfkcZ_.d.ts +172 -0
  20. package/package.json +14 -13
  21. package/src/client/index.ts +18 -0
  22. package/src/client/reservations.ts +336 -0
  23. package/src/hooks/createDataHook.test.ts +534 -0
  24. package/src/hooks/createDataHook.ts +20 -13
  25. package/src/hooks/index.ts +2 -0
  26. package/src/hooks/useContacts.test.ts +159 -0
  27. package/src/hooks/useContacts.ts +176 -0
  28. package/src/hooks/useReservations.ts +145 -0
  29. package/src/mutations/contacts.test.ts +604 -0
  30. package/src/mutations/contacts.ts +554 -0
  31. package/src/mutations/index.ts +32 -0
  32. package/src/mutations/productInstances/productInstances.test.ts +3 -3
  33. package/src/mutations/reservations.test.ts +459 -0
  34. package/src/mutations/reservations.ts +452 -0
  35. package/src/queries/contacts.test.ts +505 -0
  36. package/src/queries/contacts.ts +237 -0
  37. package/src/queries/index.ts +21 -0
  38. package/src/queries/reservations.test.ts +374 -0
  39. package/src/queries/reservations.ts +247 -0
@@ -1,12 +1,8 @@
1
1
  import { Ref, ComputedRef } from 'vue';
2
- import { Brand, Account, User, Product, ProductInstance } from '@htlkg/core/types';
3
- import { b as CreateProductInstanceInput, e as UpdateProductInstanceInput } from '../productInstances-BA3cNsYc.js';
4
- export { resetSharedClient as resetClientInstance } from '../client/index.js';
5
- import 'aws-amplify/data';
6
- import 'aws-amplify';
7
- import '../server/index.js';
8
- import 'astro';
9
- import 'aws-amplify/api/internals';
2
+ import { Brand, Account, User, Product, ProductInstance, Contact } from '@htlkg/core/types';
3
+ import { C as CreateProductInstanceInput, U as UpdateProductInstanceInput } from '../productInstances-BpQv1oLS.js';
4
+ import { R as Reservation } from '../reservations-C0FNm__0.js';
5
+ import '../common-DSxswsZ3.js';
10
6
 
11
7
  /**
12
8
  * Data Hook Factory
@@ -62,7 +58,7 @@ interface DataHookReturn<T, TComputed extends Record<string, any> = Record<strin
62
58
  [K in keyof TComputed]: ComputedRef<TComputed[K]>;
63
59
  };
64
60
  }
65
-
61
+ declare function resetClientInstance(): void;
66
62
  /**
67
63
  * Creates a reusable data hook for a specific model
68
64
  *
@@ -379,4 +375,160 @@ interface UseProductInstancesReturn {
379
375
  */
380
376
  declare function useProductInstances(options?: UseProductInstancesOptions): UseProductInstancesReturn;
381
377
 
382
- export { type BaseHookOptions, type CreateDataHookOptions, type DataHookReturn, type InferHookReturn, type UseAccountsOptions, type UseAccountsReturn, type UseBrandsOptions, type UseBrandsReturn, type UseProductInstancesOptions, type UseProductInstancesReturn, type UseProductsOptions, type UseProductsReturn, type UseUsersOptions, type UseUsersReturn, createDataHook, useAccounts, useBrands, useProductInstances, useProducts, useUsers };
378
+ /**
379
+ * useReservations Hook
380
+ *
381
+ * Vue composable for fetching and managing reservation data with reactive state.
382
+ * Provides loading states, error handling, pagination, and refetch capabilities.
383
+ */
384
+
385
+ interface UseReservationsOptions extends BaseHookOptions {
386
+ /** Filter by brand ID */
387
+ brandId?: string;
388
+ /** Filter by start date (check-in date >= startDate) */
389
+ startDate?: string;
390
+ /** Filter by end date (check-in date <= endDate) */
391
+ endDate?: string;
392
+ /** Filter by reservation status */
393
+ status?: Reservation["status"];
394
+ /** Filter by contact/visit ID */
395
+ contactId?: string;
396
+ /** Pagination token for fetching next page */
397
+ nextToken?: string;
398
+ }
399
+ interface UseReservationsReturn {
400
+ /** Reactive array of reservations */
401
+ reservations: Ref<Reservation[]>;
402
+ /** Computed array of confirmed reservations */
403
+ confirmedReservations: ComputedRef<Reservation[]>;
404
+ /** Computed array of active reservations (confirmed or checked_in) */
405
+ activeReservations: ComputedRef<Reservation[]>;
406
+ /** Loading state */
407
+ loading: Ref<boolean>;
408
+ /** Error state */
409
+ error: Ref<Error | null>;
410
+ /** Refetch reservations */
411
+ refetch: () => Promise<void>;
412
+ }
413
+ /**
414
+ * Composable for fetching and managing reservations
415
+ *
416
+ * @example
417
+ * ```typescript
418
+ * import { useReservations } from '@htlkg/data/hooks';
419
+ *
420
+ * const { reservations, loading, error, refetch } = useReservations({
421
+ * brandId: 'brand-123',
422
+ * startDate: '2026-01-01',
423
+ * endDate: '2026-01-31',
424
+ * status: 'confirmed'
425
+ * });
426
+ * ```
427
+ *
428
+ * @example With contact filter
429
+ * ```typescript
430
+ * const { reservations, loading } = useReservations({
431
+ * contactId: 'contact-123',
432
+ * limit: 50
433
+ * });
434
+ * ```
435
+ *
436
+ * @example With computed properties
437
+ * ```typescript
438
+ * const { reservations, activeReservations, confirmedReservations } = useReservations({
439
+ * brandId: 'brand-123'
440
+ * });
441
+ *
442
+ * // activeReservations includes confirmed + checked_in
443
+ * // confirmedReservations includes only confirmed
444
+ * ```
445
+ */
446
+ declare function useReservations(options?: UseReservationsOptions): UseReservationsReturn;
447
+
448
+ /**
449
+ * useContacts Hook
450
+ *
451
+ * Vue composable for fetching and managing contact data with reactive state.
452
+ * Provides loading states, error handling, search, pagination, and refetch capabilities.
453
+ */
454
+
455
+ interface UseContactsOptions extends BaseHookOptions {
456
+ /** Filter by brand ID */
457
+ brandId?: string;
458
+ /** Search query (searches email, firstName, lastName) */
459
+ search?: string;
460
+ /** Filter by GDPR consent */
461
+ gdprConsent?: boolean;
462
+ /** Filter by marketing opt-in */
463
+ marketingOptIn?: boolean;
464
+ /** Filter by tags (contact must have at least one of these tags) */
465
+ tags?: string[];
466
+ /** Pagination token for fetching next page */
467
+ nextToken?: string;
468
+ }
469
+ interface UseContactsReturn {
470
+ /** Reactive array of contacts */
471
+ contacts: Ref<Contact[]>;
472
+ /** Computed array of contacts with GDPR consent */
473
+ consentedContacts: ComputedRef<Contact[]>;
474
+ /** Computed array of contacts opted-in for marketing */
475
+ marketingContacts: ComputedRef<Contact[]>;
476
+ /** Loading state */
477
+ loading: Ref<boolean>;
478
+ /** Error state */
479
+ error: Ref<Error | null>;
480
+ /** Refetch contacts */
481
+ refetch: () => Promise<void>;
482
+ }
483
+ /**
484
+ * Composable for fetching and managing contacts
485
+ *
486
+ * @example
487
+ * ```typescript
488
+ * import { useContacts } from '@htlkg/data/hooks';
489
+ *
490
+ * const { contacts, loading, error, refetch } = useContacts({
491
+ * brandId: 'brand-123',
492
+ * limit: 25
493
+ * });
494
+ * ```
495
+ *
496
+ * @example With search
497
+ * ```typescript
498
+ * const { contacts, loading } = useContacts({
499
+ * brandId: 'brand-123',
500
+ * search: 'john',
501
+ * limit: 25
502
+ * });
503
+ * ```
504
+ *
505
+ * @example With GDPR and marketing filters
506
+ * ```typescript
507
+ * const { contacts, marketingContacts } = useContacts({
508
+ * brandId: 'brand-123',
509
+ * gdprConsent: true,
510
+ * marketingOptIn: true
511
+ * });
512
+ * ```
513
+ *
514
+ * @example With computed properties
515
+ * ```typescript
516
+ * const { contacts, consentedContacts, marketingContacts } = useContacts({
517
+ * brandId: 'brand-123'
518
+ * });
519
+ *
520
+ * // consentedContacts - contacts with GDPR consent
521
+ * // marketingContacts - contacts opted-in for marketing
522
+ * ```
523
+ *
524
+ * @example With tag filtering
525
+ * ```typescript
526
+ * const { contacts } = useContacts({
527
+ * brandId: 'brand-123',
528
+ * tags: ['vip', 'returning']
529
+ * });
530
+ * ```
531
+ */
532
+ declare function useContacts(options?: UseContactsOptions): UseContactsReturn;
533
+
534
+ export { type BaseHookOptions, type CreateDataHookOptions, type DataHookReturn, type InferHookReturn, type UseAccountsOptions, type UseAccountsReturn, type UseBrandsOptions, type UseBrandsReturn, type UseContactsOptions, type UseContactsReturn, type UseProductInstancesOptions, type UseProductInstancesReturn, type UseProductsOptions, type UseProductsReturn, type UseReservationsOptions, type UseReservationsReturn, type UseUsersOptions, type UseUsersReturn, createDataHook, resetClientInstance, useAccounts, useBrands, useContacts, useProductInstances, useProducts, useReservations, useUsers };
@@ -1,38 +1,61 @@
1
1
  // src/hooks/createDataHook.ts
2
2
  import { ref, computed, onMounted } from "vue";
3
3
 
4
- // src/client/index.ts
5
- import { generateClient as generateDataClient } from "aws-amplify/data";
6
- import { Amplify } from "aws-amplify";
7
-
8
- // src/client/server.ts
9
- import {
10
- generateClientWithAmplifyInstance
11
- } from "aws-amplify/api/internals";
12
- import { getAmplifyServerContext } from "aws-amplify/adapter-core/internals";
13
- import { createRunWithAmplifyServerContext, createLogger } from "@htlkg/core/amplify-astro-adapter";
14
- var log = createLogger("server-client");
15
-
16
- // src/client/index.ts
17
- var sharedClientInstance = null;
18
- function getSharedClient() {
19
- if (!sharedClientInstance) {
20
- sharedClientInstance = generateDataClient();
4
+ // src/client/proxy.ts
5
+ var DEFAULT_ENDPOINT = "/api/graphql";
6
+ async function query(model, operation, data, options) {
7
+ return proxyRequest(model, operation, data, options);
8
+ }
9
+ async function proxyRequest(model, operation, data, options) {
10
+ const endpoint = options?.endpoint ?? DEFAULT_ENDPOINT;
11
+ try {
12
+ const response = await fetch(endpoint, {
13
+ method: "POST",
14
+ headers: {
15
+ "Content-Type": "application/json"
16
+ },
17
+ credentials: "include",
18
+ // Important: include cookies
19
+ ...options?.fetchOptions,
20
+ body: JSON.stringify({ model, operation, data })
21
+ });
22
+ const result = await response.json();
23
+ if (response.status === 401) {
24
+ console.error("[GraphQL Proxy] Unauthorized - session may have expired");
25
+ }
26
+ return result;
27
+ } catch (error) {
28
+ console.error("[GraphQL Proxy] Request failed:", error);
29
+ return {
30
+ data: null,
31
+ errors: [
32
+ {
33
+ message: error instanceof Error ? error.message : "Network error"
34
+ }
35
+ ]
36
+ };
21
37
  }
22
- return sharedClientInstance;
23
38
  }
24
- function resetSharedClient() {
25
- sharedClientInstance = null;
39
+ function hasErrors(response) {
40
+ return !!response.errors && response.errors.length > 0;
41
+ }
42
+ function getErrorMessage(response) {
43
+ if (!response.errors || response.errors.length === 0) {
44
+ return null;
45
+ }
46
+ return response.errors[0].message;
26
47
  }
27
48
 
28
49
  // src/hooks/createDataHook.ts
50
+ function resetClientInstance() {
51
+ }
29
52
  function createDataHook(config) {
30
53
  const {
31
54
  model,
32
55
  defaultLimit,
33
56
  selectionSet,
34
57
  transform,
35
- buildFilter: buildFilter5,
58
+ buildFilter: buildFilter7,
36
59
  computedProperties,
37
60
  dataPropertyName = "data"
38
61
  } = config;
@@ -42,8 +65,8 @@ function createDataHook(config) {
42
65
  const loading = ref(false);
43
66
  const error = ref(null);
44
67
  const getFilter = () => {
45
- if (buildFilter5) {
46
- return buildFilter5(options);
68
+ if (buildFilter7) {
69
+ return buildFilter7(options);
47
70
  }
48
71
  return baseFilter && Object.keys(baseFilter).length > 0 ? baseFilter : void 0;
49
72
  };
@@ -51,19 +74,22 @@ function createDataHook(config) {
51
74
  loading.value = true;
52
75
  error.value = null;
53
76
  try {
54
- const client = getSharedClient();
55
- const queryOptions = {
56
- filter: getFilter(),
57
- limit
58
- };
77
+ const queryOptions = {};
78
+ const filter = getFilter();
79
+ if (filter) {
80
+ queryOptions.filter = filter;
81
+ }
82
+ if (limit) {
83
+ queryOptions.limit = limit;
84
+ }
59
85
  if (selectionSet) {
60
86
  queryOptions.selectionSet = selectionSet;
61
87
  }
62
- const { data: responseData, errors } = await client.models[model].list(queryOptions);
63
- if (errors) {
64
- throw new Error(errors[0]?.message || `Failed to fetch ${model}`);
88
+ const response = await query(model, "list", queryOptions);
89
+ if (hasErrors(response)) {
90
+ throw new Error(getErrorMessage(response) || `Failed to fetch ${model}`);
65
91
  }
66
- const items = responseData || [];
92
+ const items = response.data || [];
67
93
  data.value = transform ? items.map(transform) : items;
68
94
  } catch (e) {
69
95
  error.value = e;
@@ -198,6 +224,27 @@ function useProducts(options = {}) {
198
224
  };
199
225
  }
200
226
 
227
+ // src/client/index.ts
228
+ import { generateClient as generateDataClient } from "aws-amplify/data";
229
+ import { Amplify } from "aws-amplify";
230
+
231
+ // src/client/server.ts
232
+ import {
233
+ generateClientWithAmplifyInstance
234
+ } from "aws-amplify/api/internals";
235
+ import { getAmplifyServerContext } from "aws-amplify/adapter-core/internals";
236
+ import { createRunWithAmplifyServerContext, createLogger } from "@htlkg/core/amplify-astro-adapter";
237
+ var log = createLogger("server-client");
238
+
239
+ // src/client/index.ts
240
+ var sharedClientInstance = null;
241
+ function getSharedClient() {
242
+ if (!sharedClientInstance) {
243
+ sharedClientInstance = generateDataClient();
244
+ }
245
+ return sharedClientInstance;
246
+ }
247
+
201
248
  // src/mutations/productInstances/productInstances.ts
202
249
  import { getClientUser } from "@htlkg/core/auth";
203
250
  import { getCurrentTimestamp } from "@htlkg/core/utils";
@@ -417,13 +464,124 @@ function useProductInstances(options = {}) {
417
464
  toggleEnabled
418
465
  };
419
466
  }
467
+
468
+ // src/hooks/useReservations.ts
469
+ function buildFilter5(options) {
470
+ const conditions = [];
471
+ if (options.brandId) {
472
+ conditions.push({ brandId: { eq: options.brandId } });
473
+ }
474
+ if (options.status) {
475
+ conditions.push({ status: { eq: options.status } });
476
+ }
477
+ if (options.contactId) {
478
+ conditions.push({ visitId: { eq: options.contactId } });
479
+ }
480
+ if (options.startDate) {
481
+ conditions.push({ checkIn: { ge: options.startDate } });
482
+ }
483
+ if (options.endDate) {
484
+ conditions.push({ checkIn: { le: options.endDate } });
485
+ }
486
+ if (options.filter) {
487
+ conditions.push(options.filter);
488
+ }
489
+ if (conditions.length === 0) {
490
+ return void 0;
491
+ }
492
+ if (conditions.length === 1) {
493
+ return conditions[0];
494
+ }
495
+ return { and: conditions };
496
+ }
497
+ var useReservationsInternal = createDataHook({
498
+ model: "Reservation",
499
+ dataPropertyName: "reservations",
500
+ buildFilter: buildFilter5,
501
+ computedProperties: {
502
+ confirmedReservations: (reservations) => reservations.filter((r) => r.status === "confirmed"),
503
+ activeReservations: (reservations) => reservations.filter((r) => r.status === "confirmed" || r.status === "checked_in")
504
+ }
505
+ });
506
+ function useReservations(options = {}) {
507
+ const result = useReservationsInternal(options);
508
+ return {
509
+ reservations: result.reservations,
510
+ confirmedReservations: result.confirmedReservations,
511
+ activeReservations: result.activeReservations,
512
+ loading: result.loading,
513
+ error: result.error,
514
+ refetch: result.refetch
515
+ };
516
+ }
517
+
518
+ // src/hooks/useContacts.ts
519
+ function buildFilter6(options) {
520
+ const conditions = [];
521
+ if (options.brandId) {
522
+ conditions.push({ brandId: { eq: options.brandId } });
523
+ }
524
+ if (options.search) {
525
+ conditions.push({
526
+ or: [
527
+ { email: { contains: options.search } },
528
+ { firstName: { contains: options.search } },
529
+ { lastName: { contains: options.search } }
530
+ ]
531
+ });
532
+ }
533
+ if (options.gdprConsent !== void 0) {
534
+ conditions.push({ gdprConsent: { eq: options.gdprConsent } });
535
+ }
536
+ if (options.marketingOptIn !== void 0) {
537
+ conditions.push({ marketingOptIn: { eq: options.marketingOptIn } });
538
+ }
539
+ if (options.tags && options.tags.length > 0) {
540
+ const tagConditions = options.tags.map((tag) => ({
541
+ tags: { contains: tag }
542
+ }));
543
+ conditions.push({ or: tagConditions });
544
+ }
545
+ if (options.filter) {
546
+ conditions.push(options.filter);
547
+ }
548
+ if (conditions.length === 0) {
549
+ return void 0;
550
+ }
551
+ if (conditions.length === 1) {
552
+ return conditions[0];
553
+ }
554
+ return { and: conditions };
555
+ }
556
+ var useContactsInternal = createDataHook({
557
+ model: "Contact",
558
+ dataPropertyName: "contacts",
559
+ buildFilter: buildFilter6,
560
+ computedProperties: {
561
+ consentedContacts: (contacts) => contacts.filter((c) => c.gdprConsent === true),
562
+ marketingContacts: (contacts) => contacts.filter((c) => c.marketingOptIn === true)
563
+ }
564
+ });
565
+ function useContacts(options = {}) {
566
+ const result = useContactsInternal(options);
567
+ return {
568
+ contacts: result.contacts,
569
+ consentedContacts: result.consentedContacts,
570
+ marketingContacts: result.marketingContacts,
571
+ loading: result.loading,
572
+ error: result.error,
573
+ refetch: result.refetch
574
+ };
575
+ }
420
576
  export {
421
577
  createDataHook,
422
- resetSharedClient as resetClientInstance,
578
+ resetClientInstance,
423
579
  useAccounts,
424
580
  useBrands,
581
+ useContacts,
425
582
  useProductInstances,
426
583
  useProducts,
584
+ useReservations,
427
585
  useUsers
428
586
  };
429
587
  //# sourceMappingURL=index.js.map