@tummycrypt/acuity-middleware 0.1.0 → 0.1.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.
Files changed (148) hide show
  1. package/dist/adapters/acuity-scraper.d.ts +8 -0
  2. package/dist/adapters/acuity-scraper.d.ts.map +1 -0
  3. package/dist/adapters/acuity-scraper.js +8 -0
  4. package/dist/adapters/acuity-scraper.js.map +1 -0
  5. package/dist/adapters/types.d.ts +8 -0
  6. package/dist/adapters/types.d.ts.map +1 -0
  7. package/dist/adapters/types.js +8 -0
  8. package/dist/adapters/types.js.map +1 -0
  9. package/dist/core/types.d.ts +10 -0
  10. package/dist/core/types.d.ts.map +1 -0
  11. package/dist/core/types.js +2 -0
  12. package/dist/core/types.js.map +1 -0
  13. package/dist/index.d.ts +17 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +18 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/middleware/acuity-wizard.d.ts +49 -0
  18. package/dist/middleware/acuity-wizard.d.ts.map +1 -0
  19. package/dist/middleware/acuity-wizard.js +265 -0
  20. package/dist/middleware/acuity-wizard.js.map +1 -0
  21. package/dist/middleware/browser-service.d.ts +53 -0
  22. package/dist/middleware/browser-service.d.ts.map +1 -0
  23. package/dist/middleware/browser-service.js +105 -0
  24. package/dist/middleware/browser-service.js.map +1 -0
  25. package/dist/middleware/errors.d.ts +58 -0
  26. package/dist/middleware/errors.d.ts.map +1 -0
  27. package/dist/middleware/errors.js +43 -0
  28. package/dist/middleware/errors.js.map +1 -0
  29. package/{src/middleware/index.ts → dist/middleware/index.d.ts} +5 -52
  30. package/dist/middleware/index.d.ts.map +1 -0
  31. package/dist/middleware/index.js +38 -0
  32. package/dist/middleware/index.js.map +1 -0
  33. package/dist/middleware/logger.d.ts +26 -0
  34. package/dist/middleware/logger.d.ts.map +1 -0
  35. package/dist/middleware/logger.js +65 -0
  36. package/dist/middleware/logger.js.map +1 -0
  37. package/dist/middleware/remote-adapter.d.ts +45 -0
  38. package/dist/middleware/remote-adapter.d.ts.map +1 -0
  39. package/dist/middleware/remote-adapter.js +178 -0
  40. package/dist/middleware/remote-adapter.js.map +1 -0
  41. package/dist/middleware/selector-health.d.ts +44 -0
  42. package/dist/middleware/selector-health.d.ts.map +1 -0
  43. package/dist/middleware/selector-health.js +144 -0
  44. package/dist/middleware/selector-health.js.map +1 -0
  45. package/dist/middleware/selectors.d.ts +108 -0
  46. package/dist/middleware/selectors.d.ts.map +1 -0
  47. package/dist/middleware/selectors.js +249 -0
  48. package/dist/middleware/selectors.js.map +1 -0
  49. package/dist/middleware/server.d.ts +34 -0
  50. package/dist/middleware/server.d.ts.map +1 -0
  51. package/dist/middleware/server.js +377 -0
  52. package/dist/middleware/server.js.map +1 -0
  53. package/dist/middleware/service-resolver.d.ts +46 -0
  54. package/dist/middleware/service-resolver.d.ts.map +1 -0
  55. package/dist/middleware/service-resolver.js +274 -0
  56. package/dist/middleware/service-resolver.js.map +1 -0
  57. package/dist/middleware/slot-parser.d.ts +29 -0
  58. package/dist/middleware/slot-parser.d.ts.map +1 -0
  59. package/dist/middleware/slot-parser.js +50 -0
  60. package/dist/middleware/slot-parser.js.map +1 -0
  61. package/dist/middleware/steps/__tests__/fixtures.d.ts +14 -0
  62. package/dist/middleware/steps/__tests__/fixtures.d.ts.map +1 -0
  63. package/dist/middleware/steps/__tests__/fixtures.js +204 -0
  64. package/dist/middleware/steps/__tests__/fixtures.js.map +1 -0
  65. package/dist/middleware/steps/bypass-payment.d.ts +54 -0
  66. package/dist/middleware/steps/bypass-payment.d.ts.map +1 -0
  67. package/dist/middleware/steps/bypass-payment.js +164 -0
  68. package/dist/middleware/steps/bypass-payment.js.map +1 -0
  69. package/dist/middleware/steps/extract-business.d.ts +93 -0
  70. package/dist/middleware/steps/extract-business.d.ts.map +1 -0
  71. package/dist/middleware/steps/extract-business.js +170 -0
  72. package/dist/middleware/steps/extract-business.js.map +1 -0
  73. package/dist/middleware/steps/extract.d.ts +41 -0
  74. package/dist/middleware/steps/extract.d.ts.map +1 -0
  75. package/dist/middleware/steps/extract.js +128 -0
  76. package/dist/middleware/steps/extract.js.map +1 -0
  77. package/dist/middleware/steps/fill-form.d.ts +45 -0
  78. package/dist/middleware/steps/fill-form.d.ts.map +1 -0
  79. package/dist/middleware/steps/fill-form.js +262 -0
  80. package/dist/middleware/steps/fill-form.js.map +1 -0
  81. package/dist/middleware/steps/index.d.ts +12 -0
  82. package/dist/middleware/steps/index.d.ts.map +1 -0
  83. package/dist/middleware/steps/index.js +12 -0
  84. package/dist/middleware/steps/index.js.map +1 -0
  85. package/dist/middleware/steps/navigate.d.ts +51 -0
  86. package/dist/middleware/steps/navigate.d.ts.map +1 -0
  87. package/dist/middleware/steps/navigate.js +391 -0
  88. package/dist/middleware/steps/navigate.js.map +1 -0
  89. package/dist/middleware/steps/read-availability.d.ts +37 -0
  90. package/dist/middleware/steps/read-availability.d.ts.map +1 -0
  91. package/dist/middleware/steps/read-availability.js +298 -0
  92. package/dist/middleware/steps/read-availability.js.map +1 -0
  93. package/dist/middleware/steps/read-slots.d.ts +33 -0
  94. package/dist/middleware/steps/read-slots.d.ts.map +1 -0
  95. package/dist/middleware/steps/read-slots.js +295 -0
  96. package/dist/middleware/steps/read-slots.js.map +1 -0
  97. package/dist/middleware/steps/read-via-url.d.ts +39 -0
  98. package/dist/middleware/steps/read-via-url.d.ts.map +1 -0
  99. package/dist/middleware/steps/read-via-url.js +141 -0
  100. package/dist/middleware/steps/read-via-url.js.map +1 -0
  101. package/dist/middleware/steps/submit.d.ts +22 -0
  102. package/dist/middleware/steps/submit.d.ts.map +1 -0
  103. package/dist/middleware/steps/submit.js +112 -0
  104. package/dist/middleware/steps/submit.js.map +1 -0
  105. package/dist/middleware/wizard-calendar.d.ts +37 -0
  106. package/dist/middleware/wizard-calendar.d.ts.map +1 -0
  107. package/dist/middleware/wizard-calendar.js +177 -0
  108. package/dist/middleware/wizard-calendar.js.map +1 -0
  109. package/dist/middleware/wizard-service.d.ts +30 -0
  110. package/dist/middleware/wizard-service.d.ts.map +1 -0
  111. package/dist/middleware/wizard-service.js +89 -0
  112. package/dist/middleware/wizard-service.js.map +1 -0
  113. package/dist/server.d.ts +6 -0
  114. package/dist/server.d.ts.map +1 -0
  115. package/{src/server.ts → dist/server.js} +1 -0
  116. package/dist/server.js.map +1 -0
  117. package/package.json +16 -4
  118. package/.github/workflows/build-paper.yml +0 -39
  119. package/.github/workflows/ci.yml +0 -37
  120. package/Dockerfile +0 -53
  121. package/docs/blog-post.mdx +0 -240
  122. package/docs/paper/IEEEtran.bst +0 -2409
  123. package/docs/paper/IEEEtran.cls +0 -6347
  124. package/docs/paper/acuity-middleware-paper.tex +0 -375
  125. package/docs/paper/balance.sty +0 -87
  126. package/docs/paper/references.bib +0 -231
  127. package/docs/paper.md +0 -400
  128. package/flake.nix +0 -32
  129. package/modal-app.py +0 -82
  130. package/src/adapters/acuity-scraper.ts +0 -543
  131. package/src/adapters/types.ts +0 -193
  132. package/src/core/types.ts +0 -325
  133. package/src/index.ts +0 -75
  134. package/src/middleware/acuity-wizard.ts +0 -456
  135. package/src/middleware/browser-service.ts +0 -183
  136. package/src/middleware/errors.ts +0 -70
  137. package/src/middleware/remote-adapter.ts +0 -246
  138. package/src/middleware/selectors.ts +0 -308
  139. package/src/middleware/server.ts +0 -372
  140. package/src/middleware/steps/bypass-payment.ts +0 -226
  141. package/src/middleware/steps/extract.ts +0 -174
  142. package/src/middleware/steps/fill-form.ts +0 -359
  143. package/src/middleware/steps/index.ts +0 -27
  144. package/src/middleware/steps/navigate.ts +0 -537
  145. package/src/middleware/steps/read-availability.ts +0 -399
  146. package/src/middleware/steps/read-slots.ts +0 -405
  147. package/src/middleware/steps/submit.ts +0 -168
  148. package/tsconfig.json +0 -25
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-slots.js","sourceRoot":"","sources":["../../../src/middleware/steps/read-slots.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Wizard Steps: URL-Parameter-Based Availability Reading
3
+ *
4
+ * Navigate directly to a service's calendar via ?appointmentType={id}
5
+ * query parameter, bypassing click-through category navigation
6
+ * (which breaks with collapseCategories: true).
7
+ *
8
+ * These are the primary codepath for /availability/dates and
9
+ * /availability/slots endpoints on the middleware server.
10
+ */
11
+ import { Effect, Scope } from 'effect';
12
+ import { BrowserService } from '../browser-service.js';
13
+ import { WizardStepError } from '../errors.js';
14
+ export interface UrlDateResult {
15
+ readonly date: string;
16
+ readonly slots: number;
17
+ }
18
+ export interface UrlSlotResult {
19
+ readonly datetime: string;
20
+ readonly available: boolean;
21
+ }
22
+ /**
23
+ * Read available dates by navigating directly to a service's calendar
24
+ * via ?appointmentType={id} URL parameter.
25
+ *
26
+ * @param serviceId - Acuity numeric appointment type ID
27
+ * @param targetMonth - Optional YYYY-MM to navigate to specific month
28
+ */
29
+ export declare const readDatesViaUrl: (serviceId: string, targetMonth?: string) => Effect.Effect<UrlDateResult[], WizardStepError, BrowserService | Scope.Scope>;
30
+ /**
31
+ * Read time slots by navigating directly to a service's calendar
32
+ * via ?appointmentType={id}&date={YYYY-MM-DD} URL parameters,
33
+ * then clicking the target date tile.
34
+ *
35
+ * @param serviceId - Acuity numeric appointment type ID
36
+ * @param date - Target date in YYYY-MM-DD format
37
+ */
38
+ export declare const readSlotsViaUrl: (serviceId: string, date: string) => Effect.Effect<UrlSlotResult[], WizardStepError, BrowserService | Scope.Scope>;
39
+ //# sourceMappingURL=read-via-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-via-url.d.ts","sourceRoot":"","sources":["../../../src/middleware/steps/read-via-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAQ/C,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC5B;AAMD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAC3B,WAAW,MAAM,EACjB,cAAc,MAAM,KAClB,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,eAAe,EAAE,cAAc,GAAG,KAAK,CAAC,KAAK,CAgD5E,CAAC;AAMJ;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC3B,WAAW,MAAM,EACjB,MAAM,MAAM,KACV,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,eAAe,EAAE,cAAc,GAAG,KAAK,CAAC,KAAK,CAqE5E,CAAC"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Wizard Steps: URL-Parameter-Based Availability Reading
3
+ *
4
+ * Navigate directly to a service's calendar via ?appointmentType={id}
5
+ * query parameter, bypassing click-through category navigation
6
+ * (which breaks with collapseCategories: true).
7
+ *
8
+ * These are the primary codepath for /availability/dates and
9
+ * /availability/slots endpoints on the middleware server.
10
+ */
11
+ import { Effect } from 'effect';
12
+ import { BrowserService } from '../browser-service.js';
13
+ import { WizardStepError } from '../errors.js';
14
+ import { Selectors } from '../selectors.js';
15
+ import { parseSlotText, buildIsoDatetime } from '../slot-parser.js';
16
+ // =============================================================================
17
+ // READ DATES VIA URL PARAM
18
+ // =============================================================================
19
+ /**
20
+ * Read available dates by navigating directly to a service's calendar
21
+ * via ?appointmentType={id} URL parameter.
22
+ *
23
+ * @param serviceId - Acuity numeric appointment type ID
24
+ * @param targetMonth - Optional YYYY-MM to navigate to specific month
25
+ */
26
+ export const readDatesViaUrl = (serviceId, targetMonth) => Effect.gen(function* () {
27
+ const { acquirePage, config } = yield* BrowserService;
28
+ const page = yield* acquirePage.pipe(Effect.mapError((e) => new WizardStepError({ step: 'read-availability', message: `Browser error: ${e._tag}` })));
29
+ const url = new URL(config.baseUrl);
30
+ url.searchParams.set('appointmentType', serviceId);
31
+ if (targetMonth)
32
+ url.searchParams.set('month', targetMonth);
33
+ yield* Effect.tryPromise({
34
+ try: () => page.goto(url.toString(), { waitUntil: 'networkidle', timeout: config.timeout }),
35
+ catch: (e) => new WizardStepError({ step: 'read-availability', message: `Navigation failed: ${e}` }),
36
+ });
37
+ // Wait for calendar tiles using the Selectors registry
38
+ const calendarSelector = Selectors.calendarDay.join(', ');
39
+ yield* Effect.tryPromise({
40
+ try: () => page.waitForSelector(calendarSelector, { timeout: 10000 }),
41
+ catch: () => null,
42
+ }).pipe(Effect.ignore);
43
+ // Read enabled calendar tiles
44
+ const tileSelector = Selectors.calendarDay[0]; // .react-calendar__tile
45
+ const dates = yield* Effect.tryPromise({
46
+ try: () => page.evaluate((sel) => {
47
+ const results = [];
48
+ const neighboringClass = 'react-calendar__tile--neighboringMonth';
49
+ document.querySelectorAll(sel).forEach(tile => {
50
+ if (tile.disabled)
51
+ return;
52
+ if (tile.classList.contains(neighboringClass))
53
+ return;
54
+ const abbr = tile.querySelector('abbr');
55
+ const label = abbr?.getAttribute('aria-label') || tile.getAttribute('data-date') || '';
56
+ if (label) {
57
+ const d = new Date(label);
58
+ if (!isNaN(d.getTime())) {
59
+ results.push({ date: d.toISOString().slice(0, 10), slots: 1 });
60
+ }
61
+ }
62
+ });
63
+ return results;
64
+ }, tileSelector),
65
+ catch: (e) => new WizardStepError({ step: 'read-availability', message: `Calendar read failed: ${e}` }),
66
+ });
67
+ return dates;
68
+ });
69
+ // =============================================================================
70
+ // READ SLOTS VIA URL PARAM
71
+ // =============================================================================
72
+ /**
73
+ * Read time slots by navigating directly to a service's calendar
74
+ * via ?appointmentType={id}&date={YYYY-MM-DD} URL parameters,
75
+ * then clicking the target date tile.
76
+ *
77
+ * @param serviceId - Acuity numeric appointment type ID
78
+ * @param date - Target date in YYYY-MM-DD format
79
+ */
80
+ export const readSlotsViaUrl = (serviceId, date) => Effect.gen(function* () {
81
+ const { acquirePage, config } = yield* BrowserService;
82
+ const page = yield* acquirePage.pipe(Effect.mapError((e) => new WizardStepError({ step: 'read-slots', message: `Browser error: ${e._tag}` })));
83
+ const url = new URL(config.baseUrl);
84
+ url.searchParams.set('appointmentType', serviceId);
85
+ url.searchParams.set('date', date);
86
+ yield* Effect.tryPromise({
87
+ try: () => page.goto(url.toString(), { waitUntil: 'networkidle', timeout: config.timeout }),
88
+ catch: (e) => new WizardStepError({ step: 'read-slots', message: `Navigation failed: ${e}` }),
89
+ });
90
+ // Click the target date on the calendar
91
+ const tileSelector = Selectors.calendarDay[0];
92
+ yield* Effect.tryPromise({
93
+ try: async () => {
94
+ await page.waitForSelector(tileSelector, { timeout: 10000 }).catch(() => { });
95
+ const tiles = await page.$$(tileSelector);
96
+ for (const tile of tiles) {
97
+ const abbr = await tile.$('abbr');
98
+ const label = await abbr?.getAttribute('aria-label');
99
+ if (label) {
100
+ const d = new Date(label);
101
+ if (d.toISOString().slice(0, 10) === date) {
102
+ await tile.click();
103
+ break;
104
+ }
105
+ }
106
+ }
107
+ await page.waitForTimeout(2000);
108
+ },
109
+ catch: (e) => new WizardStepError({ step: 'read-slots', message: `Date click failed: ${e}` }),
110
+ });
111
+ // Read time slots using the Selectors registry
112
+ const slotSelector = Selectors.timeSlot[0]; // button.time-selection
113
+ const fallbackSelector = Selectors.timeSlot.join(', ');
114
+ yield* Effect.tryPromise({
115
+ try: () => page.waitForSelector(fallbackSelector, { timeout: 10000 }),
116
+ catch: () => null,
117
+ }).pipe(Effect.ignore);
118
+ const slots = yield* Effect.tryPromise({
119
+ try: () => page.evaluate((sel) => {
120
+ const results = [];
121
+ document.querySelectorAll(sel).forEach(btn => {
122
+ const raw = btn.textContent?.trim() || '';
123
+ const disabled = btn.hasAttribute('disabled');
124
+ if (raw) {
125
+ results.push({ datetime: raw, available: !disabled });
126
+ }
127
+ });
128
+ return results;
129
+ }, slotSelector),
130
+ catch: (e) => new WizardStepError({ step: 'read-slots', message: `Slots read failed: ${e}` }),
131
+ });
132
+ // Parse slot text and build full ISO datetime (e.g., "4:00 PM" → "2026-04-01T16:00:00")
133
+ return slots.map(s => {
134
+ const parsed = parseSlotText(s.datetime);
135
+ return {
136
+ datetime: parsed ? buildIsoDatetime(date, parsed.time) : s.datetime,
137
+ available: s.available,
138
+ };
139
+ });
140
+ });
141
+ //# sourceMappingURL=read-via-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-via-url.js","sourceRoot":"","sources":["../../../src/middleware/steps/read-via-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAS,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAgBpE,gFAAgF;AAChF,2BAA2B;AAC3B,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC9B,SAAiB,EACjB,WAAoB,EAC4D,EAAE,CAClF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IACnB,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC;IACtD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI,CACnC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAC/G,CAAC;IAEF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;IACnD,IAAI,WAAW;QAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAE5D,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QACxB,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QAC3F,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,sBAAsB,CAAC,EAAE,EAAE,CAAC;KACpG,CAAC,CAAC;IAEH,uDAAuD;IACvD,MAAM,gBAAgB,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1D,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QACxB,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACrE,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI;KACjB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEvB,8BAA8B;IAC9B,MAAM,YAAY,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB;IACvE,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QACtC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;YAChC,MAAM,OAAO,GAA2C,EAAE,CAAC;YAC3D,MAAM,gBAAgB,GAAG,wCAAwC,CAAC;YAClE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBAC7C,IAAK,IAA0B,CAAC,QAAQ;oBAAE,OAAO;gBACjD,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC;oBAAE,OAAO;gBAEtD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;gBACxC,MAAM,KAAK,GAAG,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;gBACvF,IAAI,KAAK,EAAE,CAAC;oBACX,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;oBAC1B,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;wBACzB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;oBAChE,CAAC;gBACF,CAAC;YACF,CAAC,CAAC,CAAC;YACH,OAAO,OAAO,CAAC;QAChB,CAAC,EAAE,YAAY,CAAC;QAChB,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,yBAAyB,CAAC,EAAE,EAAE,CAAC;KACvG,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACd,CAAC,CAAC,CAAC;AAEJ,gFAAgF;AAChF,2BAA2B;AAC3B,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC9B,SAAiB,EACjB,IAAY,EACoE,EAAE,CAClF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IACnB,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC;IACtD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI,CACnC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CACxG,CAAC;IAEF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;IACnD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAEnC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QACxB,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QAC3F,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,sBAAsB,CAAC,EAAE,EAAE,CAAC;KAC7F,CAAC,CAAC;IAEH,wCAAwC;IACxC,MAAM,YAAY,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC9C,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QACxB,GAAG,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAC7E,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;YAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBAC1B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBAClC,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;gBACrD,IAAI,KAAK,EAAE,CAAC;oBACX,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;oBAC1B,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;wBAC3C,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;wBACnB,MAAM;oBACP,CAAC;gBACF,CAAC;YACF,CAAC;YACD,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;QACD,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,sBAAsB,CAAC,EAAE,EAAE,CAAC;KAC7F,CAAC,CAAC;IAEH,+CAA+C;IAC/C,MAAM,YAAY,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB;IACpE,MAAM,gBAAgB,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QACxB,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACrE,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI;KACjB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEvB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QACtC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;YAChC,MAAM,OAAO,GAAoD,EAAE,CAAC;YACpE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBAC5C,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;gBAC1C,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;gBAC9C,IAAI,GAAG,EAAE,CAAC;oBACT,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACvD,CAAC;YACF,CAAC,CAAC,CAAC;YACH,OAAO,OAAO,CAAC;QAChB,CAAC,EAAE,YAAY,CAAC;QAChB,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,sBAAsB,CAAC,EAAE,EAAE,CAAC;KAC7F,CAAC,CAAC;IAEH,wFAAwF;IACxF,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;QACpB,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACzC,OAAO;YACN,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ;YACnE,SAAS,EAAE,CAAC,CAAC,SAAS;SACtB,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Wizard Step: Submit Booking
3
+ *
4
+ * Clicks the submit/complete button and waits for the confirmation page.
5
+ * Handles the race between successful navigation to confirmation
6
+ * and validation error display.
7
+ */
8
+ import { Effect } from 'effect';
9
+ import { BrowserService } from '../browser-service.js';
10
+ import { WizardStepError } from '../errors.js';
11
+ export interface SubmitResult {
12
+ readonly submitted: boolean;
13
+ readonly confirmationPageReached: boolean;
14
+ }
15
+ /**
16
+ * Submit the booking form and wait for confirmation.
17
+ */
18
+ export declare const submitBooking: () => Effect.Effect<{
19
+ submitted: true;
20
+ confirmationPageReached: true;
21
+ }, import("../errors.js").BrowserError | WizardStepError, import("effect/Scope").Scope | BrowserService>;
22
+ //# sourceMappingURL=submit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../../../src/middleware/steps/submit.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAY,MAAM,QAAQ,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAO/C,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC;CAC1C;AAMD;;GAEG;AACH,eAAO,MAAM,aAAa;;;wGAqDxB,CAAC"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Wizard Step: Submit Booking
3
+ *
4
+ * Clicks the submit/complete button and waits for the confirmation page.
5
+ * Handles the race between successful navigation to confirmation
6
+ * and validation error display.
7
+ */
8
+ import { Effect, Schedule } from 'effect';
9
+ import { BrowserService } from '../browser-service.js';
10
+ import { WizardStepError } from '../errors.js';
11
+ import { resolveSelector, probe, Selectors } from '../selectors.js';
12
+ // =============================================================================
13
+ // IMPLEMENTATION
14
+ // =============================================================================
15
+ /**
16
+ * Submit the booking form and wait for confirmation.
17
+ */
18
+ export const submitBooking = () => Effect.gen(function* () {
19
+ const { acquirePage } = yield* BrowserService;
20
+ const page = yield* acquirePage;
21
+ // Find submit button
22
+ const submitBtn = yield* resolveSelector(page, Selectors.submitButton, 10000).pipe(Effect.catchTag('SelectorError', () => Effect.fail(new WizardStepError({
23
+ step: 'submit',
24
+ message: 'Submit button not found. The wizard may not have advanced to the final step.',
25
+ }))));
26
+ // Click submit
27
+ yield* Effect.tryPromise({
28
+ try: () => submitBtn.element.click(),
29
+ catch: (e) => new WizardStepError({
30
+ step: 'submit',
31
+ message: `Failed to click submit: ${e instanceof Error ? e.message : String(e)}`,
32
+ cause: e,
33
+ }),
34
+ });
35
+ // Wait for either confirmation page or error
36
+ const outcome = yield* waitForOutcome(page);
37
+ if (!outcome.confirmationPageReached) {
38
+ return yield* Effect.fail(new WizardStepError({
39
+ step: 'submit',
40
+ message: outcome.errorMessage
41
+ ? `Booking submission failed: ${outcome.errorMessage}`
42
+ : 'Booking submission did not reach confirmation page',
43
+ }));
44
+ }
45
+ return {
46
+ submitted: true,
47
+ confirmationPageReached: true,
48
+ };
49
+ }).pipe(
50
+ // Retry once on transient navigation failure
51
+ Effect.retry({
52
+ times: 1,
53
+ schedule: Schedule.spaced('2 seconds'),
54
+ while: (e) => e._tag === 'WizardStepError' && e.message.includes('did not reach'),
55
+ }));
56
+ /**
57
+ * Race between confirmation page appearing and error message appearing.
58
+ * Polls both conditions until one is met or timeout.
59
+ */
60
+ const waitForOutcome = (page) => Effect.gen(function* () {
61
+ const maxWait = 60000;
62
+ const pollInterval = 1000;
63
+ const start = Date.now();
64
+ while (Date.now() - start < maxWait) {
65
+ // Check for confirmation page via selectors
66
+ const hasConfirmation = yield* probe(page, 'confirmationPage');
67
+ if (hasConfirmation) {
68
+ return { confirmationPageReached: true, errorMessage: null };
69
+ }
70
+ // Check for confirmation via URL pattern (Acuity redirects after booking)
71
+ const url = page.url();
72
+ if (/\/(confirmation|confirmed|thank-you|complete)/i.test(url)) {
73
+ return { confirmationPageReached: true, errorMessage: null };
74
+ }
75
+ // Check for confirmation text anywhere on page
76
+ const hasConfirmText = yield* Effect.tryPromise({
77
+ try: () => page
78
+ .$eval('body', (el) => {
79
+ const text = el.textContent?.toLowerCase() ?? '';
80
+ return text.includes('booking confirmed') ||
81
+ text.includes('appointment confirmed') ||
82
+ text.includes('successfully booked') ||
83
+ text.includes('your appointment is scheduled');
84
+ })
85
+ .catch(() => false),
86
+ catch: () => false,
87
+ }).pipe(Effect.orElseSucceed(() => false));
88
+ if (hasConfirmText) {
89
+ return { confirmationPageReached: true, errorMessage: null };
90
+ }
91
+ // Check for validation/submission errors
92
+ const errorText = yield* Effect.tryPromise({
93
+ try: () => page
94
+ .$eval('.error-message, .validation-error, .form-error, .alert-danger', (el) => el.textContent?.trim() ?? null)
95
+ .catch(() => null),
96
+ catch: () => null,
97
+ }).pipe(Effect.orElseSucceed(() => null));
98
+ if (errorText) {
99
+ return { confirmationPageReached: false, errorMessage: errorText };
100
+ }
101
+ // Wait before next poll
102
+ yield* Effect.tryPromise({
103
+ try: () => page.waitForTimeout(pollInterval),
104
+ catch: () => new WizardStepError({ step: 'submit', message: 'Poll wait interrupted' }),
105
+ });
106
+ }
107
+ return {
108
+ confirmationPageReached: false,
109
+ errorMessage: 'Timed out waiting for confirmation page',
110
+ };
111
+ });
112
+ //# sourceMappingURL=submit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submit.js","sourceRoot":"","sources":["../../../src/middleware/steps/submit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Wizard Calendar Operations (shared)
3
+ *
4
+ * Consolidated calendar month parsing, navigation, and day selection
5
+ * previously duplicated across navigate.ts, read-availability.ts, read-slots.ts.
6
+ */
7
+ import { Effect } from 'effect';
8
+ import type { Page } from 'playwright-core';
9
+ import { WizardStepError } from './errors.js';
10
+ export declare const MONTH_NAMES: readonly string[];
11
+ /**
12
+ * Parse the current calendar month label (e.g. "March 2026").
13
+ *
14
+ * Retries up to 3 times with 1s wait between each attempt.
15
+ * Tries textContent first, then innerText as fallback.
16
+ * Returns null if the month cannot be determined after retries.
17
+ */
18
+ export declare const getCurrentCalendarMonth: (page: Page) => Effect.Effect<{
19
+ month: number;
20
+ year: number;
21
+ } | null, never>;
22
+ /**
23
+ * Click the prev or next calendar navigation button.
24
+ */
25
+ export declare const clickCalendarNav: (page: Page, direction: "prev" | "next", step: string) => Effect.Effect<void, WizardStepError>;
26
+ /**
27
+ * Navigate the calendar to a target month/year.
28
+ * Clicks prev/next up to 12 times to reach the target.
29
+ */
30
+ export declare const navigateToMonth: (page: Page, targetMonth: number, targetYear: number, step: string) => Effect.Effect<void, WizardStepError>;
31
+ /**
32
+ * Click a specific day tile on the calendar.
33
+ * Skips disabled tiles and neighboring-month tiles.
34
+ * Waits for time slot container to appear after clicking.
35
+ */
36
+ export declare const selectDay: (page: Page, dayOfMonth: number, step: string) => Effect.Effect<void, WizardStepError>;
37
+ //# sourceMappingURL=wizard-calendar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard-calendar.d.ts","sourceRoot":"","sources":["../../src/middleware/wizard-calendar.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAO9C,eAAO,MAAM,WAAW,EAAE,SAAS,MAAM,EAGxC,CAAC;AAMF;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,GACnC,MAAM,IAAI,KACR,MAAM,CAAC,MAAM,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,EAAE,KAAK,CA2C3D,CAAC;AAmBJ;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAC5B,MAAM,IAAI,EACV,WAAW,MAAM,GAAG,MAAM,EAC1B,MAAM,MAAM,KACV,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAuBnC,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,eAAe,GAC3B,MAAM,IAAI,EACV,aAAa,MAAM,EACnB,YAAY,MAAM,EAClB,MAAM,MAAM,KACV,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAmCnC,CAAC;AAMJ;;;;GAIG;AACH,eAAO,MAAM,SAAS,GACrB,MAAM,IAAI,EACV,YAAY,MAAM,EAClB,MAAM,MAAM,KACV,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CA2CnC,CAAC"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Wizard Calendar Operations (shared)
3
+ *
4
+ * Consolidated calendar month parsing, navigation, and day selection
5
+ * previously duplicated across navigate.ts, read-availability.ts, read-slots.ts.
6
+ */
7
+ import { Effect } from 'effect';
8
+ import { WizardStepError } from './errors.js';
9
+ import { resolveSelector, Selectors } from './selectors.js';
10
+ // =============================================================================
11
+ // MONTH NAMES
12
+ // =============================================================================
13
+ export const MONTH_NAMES = [
14
+ 'january', 'february', 'march', 'april', 'may', 'june',
15
+ 'july', 'august', 'september', 'october', 'november', 'december',
16
+ ];
17
+ // =============================================================================
18
+ // CALENDAR MONTH PARSING
19
+ // =============================================================================
20
+ /**
21
+ * Parse the current calendar month label (e.g. "March 2026").
22
+ *
23
+ * Retries up to 3 times with 1s wait between each attempt.
24
+ * Tries textContent first, then innerText as fallback.
25
+ * Returns null if the month cannot be determined after retries.
26
+ */
27
+ export const getCurrentCalendarMonth = (page) => Effect.gen(function* () {
28
+ for (let attempt = 0; attempt < 3; attempt++) {
29
+ if (attempt > 0) {
30
+ yield* Effect.tryPromise({
31
+ try: () => page.waitForSelector(Selectors.calendarMonth[0], { timeout: 3000 }),
32
+ catch: () => null,
33
+ }).pipe(Effect.ignore);
34
+ yield* Effect.tryPromise({
35
+ try: () => page.waitForTimeout(1000),
36
+ catch: () => null,
37
+ }).pipe(Effect.ignore);
38
+ }
39
+ // Try textContent first
40
+ for (const sel of Selectors.calendarMonth) {
41
+ const text = yield* Effect.tryPromise({
42
+ try: () => page.$eval(sel, (el) => el.textContent),
43
+ catch: () => null,
44
+ }).pipe(Effect.orElseSucceed(() => null));
45
+ if (text) {
46
+ const result = parseMonthLabel(text);
47
+ if (result)
48
+ return result;
49
+ }
50
+ }
51
+ // Fallback: try innerText
52
+ for (const sel of Selectors.calendarMonth) {
53
+ const text = yield* Effect.tryPromise({
54
+ try: () => page.$eval(sel, (el) => el.innerText),
55
+ catch: () => null,
56
+ }).pipe(Effect.orElseSucceed(() => null));
57
+ if (text) {
58
+ const result = parseMonthLabel(text);
59
+ if (result)
60
+ return result;
61
+ }
62
+ }
63
+ }
64
+ return null;
65
+ });
66
+ /**
67
+ * Parse a month label string like "March 2026" or "March\n2026".
68
+ */
69
+ const parseMonthLabel = (text) => {
70
+ const match = text.trim().match(/([A-Za-z]+)\s*(\d{4})/);
71
+ if (!match)
72
+ return null;
73
+ const monthIdx = MONTH_NAMES.indexOf(match[1].toLowerCase());
74
+ if (monthIdx === -1)
75
+ return null;
76
+ return { month: monthIdx, year: parseInt(match[2], 10) };
77
+ };
78
+ // =============================================================================
79
+ // CALENDAR NAVIGATION
80
+ // =============================================================================
81
+ /**
82
+ * Click the prev or next calendar navigation button.
83
+ */
84
+ export const clickCalendarNav = (page, direction, step) => Effect.gen(function* () {
85
+ const selectors = direction === 'prev' ? Selectors.calendarPrev : Selectors.calendarNext;
86
+ const { element } = yield* resolveSelector(page, selectors, 3000).pipe(Effect.catchTag('SelectorError', () => Effect.fail(new WizardStepError({
87
+ step: step,
88
+ message: `Calendar ${direction} button not found`,
89
+ }))));
90
+ yield* Effect.tryPromise({
91
+ try: async () => {
92
+ await element.click();
93
+ await page.waitForTimeout(500);
94
+ },
95
+ catch: (e) => new WizardStepError({
96
+ step: step,
97
+ message: `Failed to click calendar ${direction}: ${e}`,
98
+ }),
99
+ });
100
+ });
101
+ /**
102
+ * Navigate the calendar to a target month/year.
103
+ * Clicks prev/next up to 12 times to reach the target.
104
+ */
105
+ export const navigateToMonth = (page, targetMonth, targetYear, step) => Effect.gen(function* () {
106
+ // Ensure calendar is loaded
107
+ yield* resolveSelector(page, Selectors.calendar, 10000).pipe(Effect.catchTag('SelectorError', () => Effect.fail(new WizardStepError({
108
+ step: step,
109
+ message: 'Calendar did not load within timeout',
110
+ }))));
111
+ for (let i = 0; i < 12; i++) {
112
+ const current = yield* getCurrentCalendarMonth(page);
113
+ if (!current) {
114
+ return yield* Effect.fail(new WizardStepError({
115
+ step: step,
116
+ message: 'Could not determine current calendar month',
117
+ }));
118
+ }
119
+ if (current.month === targetMonth && current.year === targetYear)
120
+ return;
121
+ const currentFirst = new Date(current.year, current.month, 1);
122
+ const targetFirst = new Date(targetYear, targetMonth, 1);
123
+ const direction = targetFirst > currentFirst ? 'next' : 'prev';
124
+ yield* clickCalendarNav(page, direction, step);
125
+ }
126
+ // If we exhausted 12 iterations, fail
127
+ return yield* Effect.fail(new WizardStepError({
128
+ step: step,
129
+ message: `Could not navigate to ${MONTH_NAMES[targetMonth]} ${targetYear} within 12 steps`,
130
+ }));
131
+ });
132
+ // =============================================================================
133
+ // DAY SELECTION
134
+ // =============================================================================
135
+ /**
136
+ * Click a specific day tile on the calendar.
137
+ * Skips disabled tiles and neighboring-month tiles.
138
+ * Waits for time slot container to appear after clicking.
139
+ */
140
+ export const selectDay = (page, dayOfMonth, step) => Effect.gen(function* () {
141
+ const clicked = yield* Effect.tryPromise({
142
+ try: async () => {
143
+ const tiles = await page.$$(Selectors.calendarDay[0]);
144
+ for (const tile of tiles) {
145
+ const isDisabled = await tile.evaluate((el) => el.disabled);
146
+ if (isDisabled)
147
+ continue;
148
+ const classes = (await tile.getAttribute('class')) ?? '';
149
+ if (classes.includes('neighboringMonth'))
150
+ continue;
151
+ const text = await tile.textContent();
152
+ const dayNum = parseInt(text?.trim() ?? '', 10);
153
+ if (dayNum === dayOfMonth) {
154
+ await tile.click();
155
+ return true;
156
+ }
157
+ }
158
+ return false;
159
+ },
160
+ catch: (e) => new WizardStepError({
161
+ step: step,
162
+ message: `Error selecting day ${dayOfMonth}: ${e}`,
163
+ }),
164
+ });
165
+ if (!clicked) {
166
+ return yield* Effect.fail(new WizardStepError({
167
+ step: step,
168
+ message: `Day ${dayOfMonth} not available on calendar`,
169
+ }));
170
+ }
171
+ // Wait for time slots to appear
172
+ yield* resolveSelector(page, Selectors.timeSlotContainer, 10000).pipe(Effect.catchTag('SelectorError', () => Effect.fail(new WizardStepError({
173
+ step: step,
174
+ message: 'Time slots did not appear after selecting day',
175
+ }))));
176
+ });
177
+ //# sourceMappingURL=wizard-calendar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard-calendar.js","sourceRoot":"","sources":["../../src/middleware/wizard-calendar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Wizard Service Selection (shared)
3
+ *
4
+ * Consolidated clickServiceBook that uses ServiceResolver for
5
+ * resilient service name matching, previously duplicated across
6
+ * navigate.ts, read-availability.ts, read-slots.ts.
7
+ */
8
+ import { Effect, Scope } from 'effect';
9
+ import { WizardStepError } from './errors.js';
10
+ import { ServiceResolver } from './service-resolver.js';
11
+ import { BrowserService } from './browser-service.js';
12
+ export interface ServiceBookResult {
13
+ /** Acuity appointment type ID extracted from URL */
14
+ readonly appointmentTypeId: string | null;
15
+ /** Acuity calendar ID extracted from URL */
16
+ readonly calendarId: string | null;
17
+ }
18
+ /**
19
+ * Find a service on the Acuity scheduling page and click its "Book" button.
20
+ *
21
+ * Uses ServiceResolver for resilient multi-strategy matching.
22
+ * Waits for the calendar page to load after clicking Book.
23
+ * Returns extracted IDs from the URL.
24
+ *
25
+ * @param serviceName - The service name to search for
26
+ * @param appointmentTypeId - Optional Acuity numeric ID for ID-based matching
27
+ * @param step - Step label for error messages (e.g., 'navigate', 'read-availability')
28
+ */
29
+ export declare const clickServiceBook: (serviceName: string, appointmentTypeId?: string, step?: string) => Effect.Effect<ServiceBookResult, WizardStepError, BrowserService | ServiceResolver | Scope.Scope>;
30
+ //# sourceMappingURL=wizard-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard-service.d.ts","sourceRoot":"","sources":["../../src/middleware/wizard-service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAMtD,MAAM,WAAW,iBAAiB;IACjC,oDAAoD;IACpD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,4CAA4C;IAC5C,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAMD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,GAC5B,aAAa,MAAM,EACnB,oBAAoB,MAAM,EAC1B,aAAiB,KACf,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,eAAe,EAAE,cAAc,GAAG,eAAe,GAAG,KAAK,CAAC,KAAK,CAmFhG,CAAC"}