@firfi/voila-sdk 0.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.
Files changed (155) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +165 -0
  3. package/dist/src/domain/cart.d.ts +10 -0
  4. package/dist/src/domain/cart.d.ts.map +1 -0
  5. package/dist/src/domain/cart.js +14 -0
  6. package/dist/src/domain/cart.js.map +1 -0
  7. package/dist/src/domain/checkout-readiness.d.ts +3 -0
  8. package/dist/src/domain/checkout-readiness.d.ts.map +1 -0
  9. package/dist/src/domain/checkout-readiness.js +18 -0
  10. package/dist/src/domain/checkout-readiness.js.map +1 -0
  11. package/dist/src/domain/parse.d.ts +5 -0
  12. package/dist/src/domain/parse.d.ts.map +1 -0
  13. package/dist/src/domain/parse.js +11 -0
  14. package/dist/src/domain/parse.js.map +1 -0
  15. package/dist/src/domain/schemas/auth.d.ts +123 -0
  16. package/dist/src/domain/schemas/auth.d.ts.map +1 -0
  17. package/dist/src/domain/schemas/auth.js +36 -0
  18. package/dist/src/domain/schemas/auth.js.map +1 -0
  19. package/dist/src/domain/schemas/cart.d.ts +1224 -0
  20. package/dist/src/domain/schemas/cart.d.ts.map +1 -0
  21. package/dist/src/domain/schemas/cart.js +123 -0
  22. package/dist/src/domain/schemas/cart.js.map +1 -0
  23. package/dist/src/domain/schemas/category-page.d.ts +187 -0
  24. package/dist/src/domain/schemas/category-page.d.ts.map +1 -0
  25. package/dist/src/domain/schemas/category-page.js +43 -0
  26. package/dist/src/domain/schemas/category-page.js.map +1 -0
  27. package/dist/src/domain/schemas/category.d.ts +25 -0
  28. package/dist/src/domain/schemas/category.d.ts.map +1 -0
  29. package/dist/src/domain/schemas/category.js +30 -0
  30. package/dist/src/domain/schemas/category.js.map +1 -0
  31. package/dist/src/domain/schemas/checkout-summary.d.ts +1035 -0
  32. package/dist/src/domain/schemas/checkout-summary.d.ts.map +1 -0
  33. package/dist/src/domain/schemas/checkout-summary.js +103 -0
  34. package/dist/src/domain/schemas/checkout-summary.js.map +1 -0
  35. package/dist/src/domain/schemas/delivery-destination.d.ts +176 -0
  36. package/dist/src/domain/schemas/delivery-destination.d.ts.map +1 -0
  37. package/dist/src/domain/schemas/delivery-destination.js +52 -0
  38. package/dist/src/domain/schemas/delivery-destination.js.map +1 -0
  39. package/dist/src/domain/schemas/index.d.ts +13 -0
  40. package/dist/src/domain/schemas/index.d.ts.map +1 -0
  41. package/dist/src/domain/schemas/index.js +13 -0
  42. package/dist/src/domain/schemas/index.js.map +1 -0
  43. package/dist/src/domain/schemas/money.d.ts +18 -0
  44. package/dist/src/domain/schemas/money.d.ts.map +1 -0
  45. package/dist/src/domain/schemas/money.js +11 -0
  46. package/dist/src/domain/schemas/money.js.map +1 -0
  47. package/dist/src/domain/schemas/product.d.ts +230 -0
  48. package/dist/src/domain/schemas/product.d.ts.map +1 -0
  49. package/dist/src/domain/schemas/product.js +32 -0
  50. package/dist/src/domain/schemas/product.js.map +1 -0
  51. package/dist/src/domain/schemas/proposition.d.ts +746 -0
  52. package/dist/src/domain/schemas/proposition.d.ts.map +1 -0
  53. package/dist/src/domain/schemas/proposition.js +110 -0
  54. package/dist/src/domain/schemas/proposition.js.map +1 -0
  55. package/dist/src/domain/schemas/search.d.ts +31 -0
  56. package/dist/src/domain/schemas/search.d.ts.map +1 -0
  57. package/dist/src/domain/schemas/search.js +16 -0
  58. package/dist/src/domain/schemas/search.js.map +1 -0
  59. package/dist/src/domain/schemas/session.d.ts +1341 -0
  60. package/dist/src/domain/schemas/session.d.ts.map +1 -0
  61. package/dist/src/domain/schemas/session.js +140 -0
  62. package/dist/src/domain/schemas/session.js.map +1 -0
  63. package/dist/src/domain/schemas/slot.d.ts +844 -0
  64. package/dist/src/domain/schemas/slot.d.ts.map +1 -0
  65. package/dist/src/domain/schemas/slot.js +130 -0
  66. package/dist/src/domain/schemas/slot.js.map +1 -0
  67. package/dist/src/index.d.ts +26 -0
  68. package/dist/src/index.d.ts.map +1 -0
  69. package/dist/src/index.js +26 -0
  70. package/dist/src/index.js.map +1 -0
  71. package/dist/src/voila/browser-login-adapter.d.ts +108 -0
  72. package/dist/src/voila/browser-login-adapter.d.ts.map +1 -0
  73. package/dist/src/voila/browser-login-adapter.js +128 -0
  74. package/dist/src/voila/browser-login-adapter.js.map +1 -0
  75. package/dist/src/voila/browser-login.d.ts +32 -0
  76. package/dist/src/voila/browser-login.d.ts.map +1 -0
  77. package/dist/src/voila/browser-login.js +86 -0
  78. package/dist/src/voila/browser-login.js.map +1 -0
  79. package/dist/src/voila/cart-mutation.d.ts +23 -0
  80. package/dist/src/voila/cart-mutation.d.ts.map +1 -0
  81. package/dist/src/voila/cart-mutation.js +52 -0
  82. package/dist/src/voila/cart-mutation.js.map +1 -0
  83. package/dist/src/voila/cart-view.d.ts +14 -0
  84. package/dist/src/voila/cart-view.d.ts.map +1 -0
  85. package/dist/src/voila/cart-view.js +45 -0
  86. package/dist/src/voila/cart-view.js.map +1 -0
  87. package/dist/src/voila/catalog-search.d.ts +27 -0
  88. package/dist/src/voila/catalog-search.d.ts.map +1 -0
  89. package/dist/src/voila/catalog-search.js +40 -0
  90. package/dist/src/voila/catalog-search.js.map +1 -0
  91. package/dist/src/voila/categories.d.ts +4 -0
  92. package/dist/src/voila/categories.d.ts.map +1 -0
  93. package/dist/src/voila/categories.js +22 -0
  94. package/dist/src/voila/categories.js.map +1 -0
  95. package/dist/src/voila/category-products.d.ts +22 -0
  96. package/dist/src/voila/category-products.d.ts.map +1 -0
  97. package/dist/src/voila/category-products.js +32 -0
  98. package/dist/src/voila/category-products.js.map +1 -0
  99. package/dist/src/voila/checkout-summary.d.ts +15 -0
  100. package/dist/src/voila/checkout-summary.d.ts.map +1 -0
  101. package/dist/src/voila/checkout-summary.js +93 -0
  102. package/dist/src/voila/checkout-summary.js.map +1 -0
  103. package/dist/src/voila/checkout-urls.d.ts +11 -0
  104. package/dist/src/voila/checkout-urls.d.ts.map +1 -0
  105. package/dist/src/voila/checkout-urls.js +23 -0
  106. package/dist/src/voila/checkout-urls.js.map +1 -0
  107. package/dist/src/voila/delivery-destinations.d.ts +22 -0
  108. package/dist/src/voila/delivery-destinations.d.ts.map +1 -0
  109. package/dist/src/voila/delivery-destinations.js +70 -0
  110. package/dist/src/voila/delivery-destinations.js.map +1 -0
  111. package/dist/src/voila/guest-bootstrap.d.ts +40 -0
  112. package/dist/src/voila/guest-bootstrap.d.ts.map +1 -0
  113. package/dist/src/voila/guest-bootstrap.js +108 -0
  114. package/dist/src/voila/guest-bootstrap.js.map +1 -0
  115. package/dist/src/voila/headers.d.ts +5 -0
  116. package/dist/src/voila/headers.d.ts.map +1 -0
  117. package/dist/src/voila/headers.js +20 -0
  118. package/dist/src/voila/headers.js.map +1 -0
  119. package/dist/src/voila/http-client.d.ts +60 -0
  120. package/dist/src/voila/http-client.d.ts.map +1 -0
  121. package/dist/src/voila/http-client.js +124 -0
  122. package/dist/src/voila/http-client.js.map +1 -0
  123. package/dist/src/voila/initial-state.d.ts +19 -0
  124. package/dist/src/voila/initial-state.d.ts.map +1 -0
  125. package/dist/src/voila/initial-state.js +117 -0
  126. package/dist/src/voila/initial-state.js.map +1 -0
  127. package/dist/src/voila/session-health.d.ts +10 -0
  128. package/dist/src/voila/session-health.d.ts.map +1 -0
  129. package/dist/src/voila/session-health.js +176 -0
  130. package/dist/src/voila/session-health.js.map +1 -0
  131. package/dist/src/voila/session-snapshot.d.ts +41 -0
  132. package/dist/src/voila/session-snapshot.d.ts.map +1 -0
  133. package/dist/src/voila/session-snapshot.js +101 -0
  134. package/dist/src/voila/session-snapshot.js.map +1 -0
  135. package/dist/src/voila/session-storage.d.ts +22 -0
  136. package/dist/src/voila/session-storage.d.ts.map +1 -0
  137. package/dist/src/voila/session-storage.js +54 -0
  138. package/dist/src/voila/session-storage.js.map +1 -0
  139. package/dist/src/voila/shopping-context.d.ts +33 -0
  140. package/dist/src/voila/shopping-context.d.ts.map +1 -0
  141. package/dist/src/voila/shopping-context.js +159 -0
  142. package/dist/src/voila/shopping-context.js.map +1 -0
  143. package/dist/src/voila/slot-urls.d.ts +22 -0
  144. package/dist/src/voila/slot-urls.d.ts.map +1 -0
  145. package/dist/src/voila/slot-urls.js +51 -0
  146. package/dist/src/voila/slot-urls.js.map +1 -0
  147. package/dist/src/voila/slots.d.ts +41 -0
  148. package/dist/src/voila/slots.d.ts.map +1 -0
  149. package/dist/src/voila/slots.js +137 -0
  150. package/dist/src/voila/slots.js.map +1 -0
  151. package/dist/src/voila/urls.d.ts +114 -0
  152. package/dist/src/voila/urls.d.ts.map +1 -0
  153. package/dist/src/voila/urls.js +197 -0
  154. package/dist/src/voila/urls.js.map +1 -0
  155. package/package.json +66 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 firfi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,165 @@
1
+ # Voila SDK
2
+
3
+ TypeScript SDK for Voila grocery search, session handling, and cart workflows.
4
+
5
+ This package wraps the same same-origin JSON endpoints used by the Voila web app. Voila does not publish a third-party customer API, so the SDK treats every live response as an unstable boundary: all I/O payloads are parsed with Effect Schema, failures are typed, and order placement is intentionally out of scope.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @firfi/voila-sdk effect
11
+ ```
12
+
13
+ The package is ESM-only and supports Node.js 20+.
14
+
15
+ ## Quick Start
16
+
17
+ ```ts
18
+ import { Either } from "effect"
19
+ import { bootstrapGuestSession, searchProducts, type VoilaTransport } from "@firfi/voila-sdk"
20
+
21
+ const responseHeadersFromFetch = (headers: Headers) => {
22
+ const setCookie = headers.getSetCookie()
23
+ const entries = Object.fromEntries(headers.entries())
24
+
25
+ return setCookie.length === 0
26
+ ? entries
27
+ : {
28
+ ...entries,
29
+ "set-cookie": setCookie
30
+ }
31
+ }
32
+
33
+ const fetchTransport: VoilaTransport = {
34
+ request: async (request) => {
35
+ const response = await fetch(request.url, {
36
+ body: request.body,
37
+ headers: request.headers,
38
+ method: request.method,
39
+ redirect: "manual"
40
+ })
41
+
42
+ return Either.right({
43
+ body: await response.text(),
44
+ headers: responseHeadersFromFetch(response.headers),
45
+ status: response.status
46
+ })
47
+ }
48
+ }
49
+
50
+ const bootstrap = await bootstrapGuestSession(fetchTransport)
51
+
52
+ if (Either.isLeft(bootstrap)) {
53
+ throw new Error(bootstrap.left._tag)
54
+ }
55
+
56
+ const search = await searchProducts(
57
+ bootstrap.right.session,
58
+ {
59
+ pageSize: 12,
60
+ query: "milk"
61
+ },
62
+ fetchTransport
63
+ )
64
+
65
+ if (Either.isLeft(search)) {
66
+ throw new Error(search.left._tag)
67
+ }
68
+
69
+ console.log(search.right.value.products.map((product) => product.name))
70
+ ```
71
+
72
+ ## What It Supports
73
+
74
+ - Guest session bootstrap from Voila homepage state.
75
+ - Product search and category product reads.
76
+ - Cart reads, item add/remove, and server-returned cart totals.
77
+ - Authenticated session health checks and authenticated cart reads.
78
+ - Delivery destination/context reads and guarded delivery context changes.
79
+ - Slot listing and guarded slot reservation input helpers.
80
+ - Checkout summary/readiness review.
81
+ - Session snapshot save/load helpers.
82
+
83
+ The SDK does not place orders. Checkout APIs stop at review/readiness so a human can confirm in Voila.
84
+
85
+ ## Authenticated Sessions
86
+
87
+ The SDK never accepts or stores a password. Use the local capture helper to log in interactively and save a session snapshot:
88
+
89
+ ```bash
90
+ pnpm auth:capture
91
+ ```
92
+
93
+ The command opens Chromium, waits for Voila session material, and writes:
94
+
95
+ ```text
96
+ local-session-snapshots/voila-auth-session.json
97
+ ```
98
+
99
+ That file is sensitive and ignored by git. Use it with `loadSdkSessionSnapshot` and `checkSessionHealth` before authenticated reads or cart mutations. See [docs/browser-login.md](docs/browser-login.md) and [docs/auth-readonly-smoke.md](docs/auth-readonly-smoke.md).
100
+
101
+ ## Public API
102
+
103
+ Import only from the package entrypoint:
104
+
105
+ ```ts
106
+ import { addCartItems, getCart, searchProducts } from "@firfi/voila-sdk"
107
+ ```
108
+
109
+ Deep imports are unsupported. See [docs/public-api.md](docs/public-api.md) for the full public surface and [docs/usage-examples.md](docs/usage-examples.md) for end-to-end examples.
110
+
111
+ ## Development
112
+
113
+ This repository follows the same quality harness as `../hulymcp`: Effect-first TypeScript, Effect Schema at I/O boundaries, strict linting, property tests, coverage gates, duplication checks, circular dependency checks, and Husky pre-commit hooks.
114
+
115
+ ```bash
116
+ pnpm install
117
+ pnpm check-all
118
+ pnpm package:audit
119
+ ```
120
+
121
+ `pnpm check-all` runs build, typecheck, circular dependency checks, lint/duplication checks, fixture audit, and coverage-gated tests.
122
+
123
+ `pnpm package:audit` builds the SDK and verifies the local npm dry-run package contents. See [docs/package-audit.md](docs/package-audit.md).
124
+
125
+ ## Live Smoke Tests
126
+
127
+ Default checks never hit Voila. Live smoke tests are opt-in:
128
+
129
+ ```bash
130
+ VOILA_LIVE_SMOKE=1 pnpm smoke:catalog-search
131
+ VOILA_LIVE_SMOKE=1 pnpm smoke:cart
132
+ VOILA_AUTH_SMOKE=1 VOILA_AUTH_SESSION_PATH=/absolute/path/to/sdk-session.json pnpm smoke:auth-readonly
133
+ VOILA_DRIFT_AUDIT=1 pnpm drift:audit
134
+ ```
135
+
136
+ The catalog smoke bootstraps a guest session and searches `milk`.
137
+
138
+ The cart smoke uses a guest session, adds one available product, reads the server cart, removes that product, and verifies cleanup.
139
+
140
+ The authenticated read-only smoke loads a caller-provided authenticated SDK session snapshot, checks session health, searches `milk`, and reads the active cart.
141
+
142
+ The endpoint drift audit bootstraps a guest session, searches `milk`, and reads the guest cart to detect likely Voila response-schema drift.
143
+
144
+ ## Release
145
+
146
+ Use the release gate before publishing:
147
+
148
+ ```bash
149
+ pnpm release:check
150
+ npm publish
151
+ ```
152
+
153
+ The package tarball intentionally contains only `package.json`, `README.md`, `LICENSE`, and `dist/src/**`. See [docs/release.md](docs/release.md).
154
+
155
+ ## Future MCP
156
+
157
+ The current package is library-first. The codebase is prepared for a future MCP server by keeping all Voila behavior behind typed SDK functions and explicit ports. The MCP package/server should be added later as a separate entrypoint or package that depends on this SDK surface rather than duplicating endpoint logic. See [docs/mcp-readiness.md](docs/mcp-readiness.md).
158
+
159
+ ## Safety
160
+
161
+ - Do not store Voila passwords.
162
+ - Treat session snapshots, browser profiles, cookies, and CSRF tokens as secrets.
163
+ - Do not log cookies, CSRF tokens, payment data, addresses, or account identifiers.
164
+ - Do not place an order without explicit caller confirmation from the latest checkout summary.
165
+ - Use [docs/safety-review-checklist.md](docs/safety-review-checklist.md) before merging changes that touch live network behavior, auth, cart mutation, slots, checkout review, fixtures, or diagnostics.
@@ -0,0 +1,10 @@
1
+ import { Either } from "effect";
2
+ import type { CartQuantityDelta } from "./schemas/index.js";
3
+ export type CartQuantityDeltaError = {
4
+ readonly _tag: "CartQuantityDeltaInvalid";
5
+ readonly message: string;
6
+ };
7
+ export declare const makeCartQuantityDelta: (productId: string, quantity: number) => Either.Either<CartQuantityDelta, CartQuantityDeltaError>;
8
+ export declare const makeAddToCartDelta: (productId: string, quantity: number) => Either.Either<CartQuantityDelta, CartQuantityDeltaError>;
9
+ export declare const makeRemoveFromCartDelta: (productId: string, quantity: number) => Either.Either<CartQuantityDelta, CartQuantityDeltaError>;
10
+ //# sourceMappingURL=cart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cart.d.ts","sourceRoot":"","sources":["../../../src/domain/cart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAG/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAG3D,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAA;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB,CAAA;AAOD,eAAO,MAAM,qBAAqB,GAChC,WAAW,MAAM,EACjB,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,sBAAsB,CAOvD,CAAA;AAEH,eAAO,MAAM,kBAAkB,GAC7B,WAAW,MAAM,EACjB,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,sBAAsB,CAAyD,CAAA;AAEnH,eAAO,MAAM,uBAAuB,GAClC,WAAW,MAAM,EACjB,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,sBAAsB,CAA0D,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { Either } from "effect";
2
+ import { parseUnknown } from "./parse.js";
3
+ import { CartQuantityDeltaSchema } from "./schemas/index.js";
4
+ const cartQuantityDeltaInvalid = () => ({
5
+ _tag: "CartQuantityDeltaInvalid",
6
+ message: "Cart quantity delta does not match the SDK schema"
7
+ });
8
+ export const makeCartQuantityDelta = (productId, quantity) => Either.mapLeft(parseUnknown(CartQuantityDeltaSchema, {
9
+ productId,
10
+ quantity
11
+ }), cartQuantityDeltaInvalid);
12
+ export const makeAddToCartDelta = (productId, quantity) => makeCartQuantityDelta(productId, Math.abs(quantity));
13
+ export const makeRemoveFromCartDelta = (productId, quantity) => makeCartQuantityDelta(productId, -Math.abs(quantity));
14
+ //# sourceMappingURL=cart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cart.js","sourceRoot":"","sources":["../../../src/domain/cart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAA;AAO5D,MAAM,wBAAwB,GAAG,GAA2B,EAAE,CAAC,CAAC;IAC9D,IAAI,EAAE,0BAA0B;IAChC,OAAO,EAAE,mDAAmD;CAC7D,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,SAAiB,EACjB,QAAgB,EAC0C,EAAE,CAC5D,MAAM,CAAC,OAAO,CACZ,YAAY,CAAC,uBAAuB,EAAE;IACpC,SAAS;IACT,QAAQ;CACT,CAAC,EACF,wBAAwB,CACzB,CAAA;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,SAAiB,EACjB,QAAgB,EAC0C,EAAE,CAAC,qBAAqB,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;AAEnH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,SAAiB,EACjB,QAAgB,EAC0C,EAAE,CAAC,qBAAqB,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { CheckoutReadinessDecision, NormalizedCheckoutSummary } from "./schemas/index.js";
2
+ export declare const decideCheckoutReadiness: (summary: NormalizedCheckoutSummary) => CheckoutReadinessDecision;
3
+ //# sourceMappingURL=checkout-readiness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkout-readiness.d.ts","sourceRoot":"","sources":["../../../src/domain/checkout-readiness.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EAGzB,yBAAyB,EAC1B,MAAM,oBAAoB,CAAA;AAiB3B,eAAO,MAAM,uBAAuB,GAClC,SAAS,yBAAyB,KACjC,yBAUF,CAAA"}
@@ -0,0 +1,18 @@
1
+ const emptyCount = 0;
2
+ const makeDecision = (summary, status, reason, canContinueToManualCheckout) => ({
3
+ canContinueToManualCheckout,
4
+ checkoutRestrictions: summary.checkoutRestrictions,
5
+ reason,
6
+ status,
7
+ warnings: summary.warnings
8
+ });
9
+ export const decideCheckoutReadiness = (summary) => {
10
+ if (!summary.canCheckout || summary.checkoutRestrictions.length > emptyCount) {
11
+ return makeDecision(summary, "blocked", "checkout-blocked", false);
12
+ }
13
+ if (summary.warnings.length > emptyCount) {
14
+ return makeDecision(summary, "needs-review", "review-signals-present", false);
15
+ }
16
+ return makeDecision(summary, "ready-for-manual-checkout", "ready-for-manual-checkout", true);
17
+ };
18
+ //# sourceMappingURL=checkout-readiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkout-readiness.js","sourceRoot":"","sources":["../../../src/domain/checkout-readiness.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,GAAG,CAAC,CAAA;AAEpB,MAAM,YAAY,GAAG,CACnB,OAAkC,EAClC,MAA+B,EAC/B,MAA+B,EAC/B,2BAAoC,EACT,EAAE,CAAC,CAAC;IAC/B,2BAA2B;IAC3B,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;IAClD,MAAM;IACN,MAAM;IACN,QAAQ,EAAE,OAAO,CAAC,QAAQ;CAC3B,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,OAAkC,EACP,EAAE;IAC7B,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,oBAAoB,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;QAC7E,OAAO,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,KAAK,CAAC,CAAA;IACpE,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;QACzC,OAAO,YAAY,CAAC,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,KAAK,CAAC,CAAA;IAC/E,CAAC;IAED,OAAO,YAAY,CAAC,OAAO,EAAE,2BAA2B,EAAE,2BAA2B,EAAE,IAAI,CAAC,CAAA;AAC9F,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { ParseResult } from "effect";
2
+ import { Either, Schema } from "effect";
3
+ export declare const parseUnknown: <A, I>(schema: Schema.Schema<A, I, never>, input: unknown) => Either.Either<A, ParseResult.ParseError>;
4
+ export declare const parseJson: (text: string) => Either.Either<unknown, Error>;
5
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../src/domain/parse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEvC,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,CAAC,EAC/B,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,EAClC,OAAO,OAAO,KACb,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,CAAC,UAAU,CAA8C,CAAA;AAExF,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAMpE,CAAA"}
@@ -0,0 +1,11 @@
1
+ import { Either, Schema } from "effect";
2
+ export const parseUnknown = (schema, input) => Schema.decodeUnknownEither(schema)(input);
3
+ export const parseJson = (text) => {
4
+ try {
5
+ return Either.right(JSON.parse(text));
6
+ }
7
+ catch (error) {
8
+ return Either.left(new Error("Invalid JSON", { cause: error }));
9
+ }
10
+ };
11
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/domain/parse.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEvC,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,MAAkC,EAClC,KAAc,EAC4B,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAA;AAExF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAiC,EAAE;IACvE,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;IACvC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;IACjE,CAAC;AACH,CAAC,CAAA"}
@@ -0,0 +1,123 @@
1
+ import { Schema } from "effect";
2
+ export declare const BrowserLoginOptionsSchema: Schema.Struct<{
3
+ timeoutMs: Schema.optionalWith<Schema.filter<Schema.filter<Schema.filter<typeof Schema.Number>>>, {
4
+ exact: true;
5
+ }>;
6
+ }>;
7
+ export type BrowserLoginOptions = Schema.Schema.Type<typeof BrowserLoginOptionsSchema>;
8
+ export declare const BrowserLoginRequestSchema: Schema.extend<Schema.Struct<{
9
+ timeoutMs: Schema.optionalWith<Schema.filter<Schema.filter<Schema.filter<typeof Schema.Number>>>, {
10
+ exact: true;
11
+ }>;
12
+ }>, Schema.Struct<{
13
+ loginUrl: typeof Schema.String;
14
+ }>>;
15
+ export type BrowserLoginRequest = Schema.Schema.Type<typeof BrowserLoginRequestSchema>;
16
+ export declare const BrowserLoginPortErrorSchema: Schema.Union<[Schema.Struct<{
17
+ _tag: Schema.Literal<["BrowserLoginUserCancelled"]>;
18
+ message: Schema.optionalWith<typeof Schema.String, {
19
+ exact: true;
20
+ }>;
21
+ }>, Schema.Struct<{
22
+ _tag: Schema.Literal<["BrowserLoginTimedOut"]>;
23
+ message: Schema.optionalWith<typeof Schema.String, {
24
+ exact: true;
25
+ }>;
26
+ }>, Schema.Struct<{
27
+ _tag: Schema.Literal<["BrowserLoginAdapterFailure"]>;
28
+ message: Schema.optionalWith<typeof Schema.String, {
29
+ exact: true;
30
+ }>;
31
+ }>]>;
32
+ export type BrowserLoginPortError = Schema.Schema.Type<typeof BrowserLoginPortErrorSchema>;
33
+ export declare const BrowserLoginCaptureSchema: Schema.Struct<{
34
+ account: Schema.optionalWith<Schema.Struct<{
35
+ displayName: Schema.optionalWith<typeof Schema.String, {
36
+ exact: true;
37
+ }>;
38
+ emailHint: Schema.optionalWith<typeof Schema.String, {
39
+ exact: true;
40
+ }>;
41
+ stableAccountIdHash: Schema.optionalWith<typeof Schema.String, {
42
+ exact: true;
43
+ }>;
44
+ }>, {
45
+ exact: true;
46
+ }>;
47
+ authenticated: typeof Schema.Boolean;
48
+ session: Schema.Struct<{
49
+ cookieJar: Schema.Schema<{
50
+ readonly cookies: readonly ({
51
+ readonly value?: string;
52
+ readonly key?: string;
53
+ } & {
54
+ readonly [x: string]: unknown;
55
+ })[];
56
+ readonly rejectPublicSuffixes: boolean;
57
+ readonly storeType: string | null;
58
+ readonly version: string;
59
+ } & {
60
+ readonly [x: string]: unknown;
61
+ }, {
62
+ readonly cookies: readonly ({
63
+ readonly value?: string;
64
+ readonly key?: string;
65
+ } & {
66
+ readonly [x: string]: unknown;
67
+ })[];
68
+ readonly rejectPublicSuffixes: boolean;
69
+ readonly storeType: string | null;
70
+ readonly version: string;
71
+ } & {
72
+ readonly [x: string]: unknown;
73
+ }, never>;
74
+ csrf: Schema.Struct<{
75
+ token: typeof Schema.String;
76
+ }>;
77
+ metadata: Schema.Struct<{
78
+ assetVersion: typeof Schema.String;
79
+ clientRouteId: typeof Schema.String;
80
+ pageViewId: typeof Schema.String;
81
+ regionId: typeof Schema.String;
82
+ }>;
83
+ }>;
84
+ }>;
85
+ export type BrowserLoginCapture = Schema.Schema.Type<typeof BrowserLoginCaptureSchema>;
86
+ export declare const BrowserLoginBrowserCookieSchema: Schema.Struct<{
87
+ domain: typeof Schema.String;
88
+ expires: Schema.optionalWith<Schema.filter<typeof Schema.Number>, {
89
+ exact: true;
90
+ }>;
91
+ httpOnly: Schema.optionalWith<typeof Schema.Boolean, {
92
+ exact: true;
93
+ }>;
94
+ name: typeof Schema.String;
95
+ path: typeof Schema.String;
96
+ sameSite: Schema.optionalWith<typeof Schema.String, {
97
+ exact: true;
98
+ }>;
99
+ secure: Schema.optionalWith<typeof Schema.Boolean, {
100
+ exact: true;
101
+ }>;
102
+ value: typeof Schema.String;
103
+ }>;
104
+ export type BrowserLoginBrowserCookie = Schema.Schema.Type<typeof BrowserLoginBrowserCookieSchema>;
105
+ export declare const BrowserLoginBrowserCookieArraySchema: Schema.Array$<Schema.Struct<{
106
+ domain: typeof Schema.String;
107
+ expires: Schema.optionalWith<Schema.filter<typeof Schema.Number>, {
108
+ exact: true;
109
+ }>;
110
+ httpOnly: Schema.optionalWith<typeof Schema.Boolean, {
111
+ exact: true;
112
+ }>;
113
+ name: typeof Schema.String;
114
+ path: typeof Schema.String;
115
+ sameSite: Schema.optionalWith<typeof Schema.String, {
116
+ exact: true;
117
+ }>;
118
+ secure: Schema.optionalWith<typeof Schema.Boolean, {
119
+ exact: true;
120
+ }>;
121
+ value: typeof Schema.String;
122
+ }>>;
123
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../src/domain/schemas/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAU/B,eAAO,MAAM,yBAAyB;;;;EAEpC,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAEtF,eAAO,MAAM,yBAAyB;;;;;;GAIrC,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAEtF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;IAavC,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAE1F,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIpC,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAEtF,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;EAS1C,CAAA;AAEF,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,+BAA+B,CAAC,CAAA;AAElG,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;GAAgD,CAAA"}
@@ -0,0 +1,36 @@
1
+ import { Schema } from "effect";
2
+ import { AuthAccountSummarySchema, SessionSnapshotSchema } from "./session.js";
3
+ const BrowserLoginTimeoutMsSchema = Schema.Number.pipe(Schema.finite(), Schema.int(), Schema.positive());
4
+ export const BrowserLoginOptionsSchema = Schema.Struct({
5
+ timeoutMs: Schema.optionalWith(BrowserLoginTimeoutMsSchema, { exact: true })
6
+ });
7
+ export const BrowserLoginRequestSchema = BrowserLoginOptionsSchema.pipe(Schema.extend(Schema.Struct({
8
+ loginUrl: Schema.String
9
+ })));
10
+ export const BrowserLoginPortErrorSchema = Schema.Union(Schema.Struct({
11
+ _tag: Schema.Literal("BrowserLoginUserCancelled"),
12
+ message: Schema.optionalWith(Schema.String, { exact: true })
13
+ }), Schema.Struct({
14
+ _tag: Schema.Literal("BrowserLoginTimedOut"),
15
+ message: Schema.optionalWith(Schema.String, { exact: true })
16
+ }), Schema.Struct({
17
+ _tag: Schema.Literal("BrowserLoginAdapterFailure"),
18
+ message: Schema.optionalWith(Schema.String, { exact: true })
19
+ }));
20
+ export const BrowserLoginCaptureSchema = Schema.Struct({
21
+ account: Schema.optionalWith(AuthAccountSummarySchema, { exact: true }),
22
+ authenticated: Schema.Boolean,
23
+ session: SessionSnapshotSchema
24
+ });
25
+ export const BrowserLoginBrowserCookieSchema = Schema.Struct({
26
+ domain: Schema.String,
27
+ expires: Schema.optionalWith(Schema.Number.pipe(Schema.finite()), { exact: true }),
28
+ httpOnly: Schema.optionalWith(Schema.Boolean, { exact: true }),
29
+ name: Schema.String,
30
+ path: Schema.String,
31
+ sameSite: Schema.optionalWith(Schema.String, { exact: true }),
32
+ secure: Schema.optionalWith(Schema.Boolean, { exact: true }),
33
+ value: Schema.String
34
+ });
35
+ export const BrowserLoginBrowserCookieArraySchema = Schema.Array(BrowserLoginBrowserCookieSchema);
36
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../../src/domain/schemas/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAE9E,MAAM,2BAA2B,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CACpD,MAAM,CAAC,MAAM,EAAE,EACf,MAAM,CAAC,GAAG,EAAE,EACZ,MAAM,CAAC,QAAQ,EAAE,CAClB,CAAA;AAED,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,MAAM,CAAC;IACrD,SAAS,EAAE,MAAM,CAAC,YAAY,CAAC,2BAA2B,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;CAC7E,CAAC,CAAA;AAIF,MAAM,CAAC,MAAM,yBAAyB,GAAG,yBAAyB,CAAC,IAAI,CACrE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM;CACxB,CAAC,CAAC,CACJ,CAAA;AAID,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,KAAK,CACrD,MAAM,CAAC,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,2BAA2B,CAAC;IACjD,OAAO,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;CAC7D,CAAC,EACF,MAAM,CAAC,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC;IAC5C,OAAO,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;CAC7D,CAAC,EACF,MAAM,CAAC,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,4BAA4B,CAAC;IAClD,OAAO,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;CAC7D,CAAC,CACH,CAAA;AAID,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,MAAM,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC,YAAY,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACvE,aAAa,EAAE,MAAM,CAAC,OAAO;IAC7B,OAAO,EAAE,qBAAqB;CAC/B,CAAC,CAAA;AAIF,MAAM,CAAC,MAAM,+BAA+B,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3D,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAClF,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC9D,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC7D,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC5D,KAAK,EAAE,MAAM,CAAC,MAAM;CACrB,CAAC,CAAA;AAIF,MAAM,CAAC,MAAM,oCAAoC,GAAG,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAA"}