@bridge-ai-dev/ecom-chat 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -163
- package/bin/cli.js +3 -2
- package/dist/cjs/ChatComponent.d.ts.map +1 -1
- package/dist/cjs/ChatComponent.js +76 -2
- package/dist/cjs/ChatComponent.js.map +1 -1
- package/dist/cjs/types.d.ts +27 -1
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/ChatComponent.js +76 -2
- package/dist/esm/ChatComponent.js.map +1 -1
- package/package.json +2 -2
- package/templates/route.ts.template +185 -15
package/README.md
CHANGED
|
@@ -1,193 +1,93 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Ecom Chat - UI
|
|
2
2
|
|
|
3
|
-
Bridge E-commerce Chat widget integration for Next.js with Litium authentication.
|
|
4
3
|
|
|
5
|
-
## Why This Package?
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
## Getting started
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
2. **Providing a React component** that fetches these cookies via the API and passes them to the chat widget
|
|
9
|
+
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
|
|
13
10
|
|
|
14
|
-
##
|
|
15
|
-
|
|
16
|
-
### Step 1: Run the Setup Command
|
|
11
|
+
## Add your files
|
|
17
12
|
|
|
18
|
-
|
|
13
|
+
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
|
|
14
|
+
- [ ] [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command:
|
|
19
15
|
|
|
20
|
-
```
|
|
21
|
-
|
|
16
|
+
```
|
|
17
|
+
cd existing_repo
|
|
18
|
+
git remote add origin https://git.bridge-delivery.com/bridge-ai/ecom-chat-ui.git
|
|
19
|
+
git branch -M main
|
|
20
|
+
git push -uf origin main
|
|
22
21
|
```
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
## Integrate with your tools
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
- [ ] [Set up project integrations](https://git.bridge-delivery.com/bridge-ai/ecom-chat-ui/-/settings/integrations)
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
npm install @bridge-ai-dev/ecom-chat
|
|
30
|
-
```
|
|
27
|
+
## Collaborate with your team
|
|
31
28
|
|
|
32
|
-
|
|
29
|
+
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
|
|
30
|
+
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
|
|
31
|
+
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
|
|
32
|
+
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
|
|
33
|
+
- [ ] [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/)
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Add the `ChatComponent` to your layout:
|
|
37
|
-
|
|
38
|
-
```tsx
|
|
39
|
-
// app/layout.tsx
|
|
40
|
-
import { ChatComponent } from '@bridge-ai-dev/ecom-chat';
|
|
41
|
-
|
|
42
|
-
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
43
|
-
return (
|
|
44
|
-
<html>
|
|
45
|
-
<body>
|
|
46
|
-
{children}
|
|
47
|
-
<ChatComponent
|
|
48
|
-
tenantId="your-tenant-uuid"
|
|
49
|
-
widgetScriptUrl="http://localhost:5173/chat-widget.js"
|
|
50
|
-
/>
|
|
51
|
-
</body>
|
|
52
|
-
</html>
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
```
|
|
35
|
+
## Test and Deploy
|
|
56
36
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
```tsx
|
|
60
|
-
<ChatComponent
|
|
61
|
-
tenantId="your-tenant-uuid"
|
|
62
|
-
widgetScriptUrl="http://localhost:5173/chat-widget.js"
|
|
63
|
-
accessToken="optional-access-token"
|
|
64
|
-
position="bottom-right"
|
|
65
|
-
backgroundColor="#6366f1"
|
|
66
|
-
foregroundColor="#ffffff"
|
|
67
|
-
size="medium"
|
|
68
|
-
borderWidth={2}
|
|
69
|
-
borderColor="#4f46e5"
|
|
70
|
-
autoPopup={false}
|
|
71
|
-
onAuthSuccess={(authData) => {
|
|
72
|
-
console.log('Auth successful, cart context:', authData.cart_context);
|
|
73
|
-
}}
|
|
74
|
-
onAuthError={(error) => {
|
|
75
|
-
console.error('Auth failed:', error.message);
|
|
76
|
-
}}
|
|
77
|
-
/>
|
|
78
|
-
```
|
|
37
|
+
Use the built-in continuous integration in GitLab.
|
|
79
38
|
|
|
80
|
-
|
|
39
|
+
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/)
|
|
40
|
+
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
|
|
41
|
+
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
|
|
42
|
+
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
|
|
43
|
+
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
|
|
81
44
|
|
|
82
|
-
|
|
83
|
-
<ChatComponent
|
|
84
|
-
tenantId="your-tenant-uuid"
|
|
85
|
-
bridgeAuthEndpoint="/api/custom-bridge-auth" // Custom API route path
|
|
86
|
-
containerId="my-chat-container" // Custom container ID
|
|
87
|
-
/>
|
|
88
|
-
```
|
|
45
|
+
***
|
|
89
46
|
|
|
90
|
-
|
|
91
|
-
If you already have access to the identity/cart tokens (e.g. in a Server Component), you can pass them directly:
|
|
47
|
+
# Editing this README
|
|
92
48
|
|
|
93
|
-
|
|
94
|
-
<ChatComponent
|
|
95
|
-
tenantId="your-tenant-uuid"
|
|
96
|
-
identity="optional-identity-token"
|
|
97
|
-
cartContext="optional-cart-jwt"
|
|
98
|
-
// ... other props
|
|
99
|
-
/>
|
|
100
|
-
```
|
|
49
|
+
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
|
|
101
50
|
|
|
102
|
-
##
|
|
103
|
-
|
|
104
|
-
### ChatComponent Props
|
|
105
|
-
|
|
106
|
-
| Prop | Type | Required | Default | Description |
|
|
107
|
-
|------|------|----------|---------|-------------|
|
|
108
|
-
| `tenantId` | `string` | ✅ | - | Your Bridge Chat tenant identifier |
|
|
109
|
-
| `identity` | `string` | ❌ | - | Identity token (skips API call if provided) |
|
|
110
|
-
| `cartContext` | `string` | ❌ | - | Cart context token (skips API call if provided) |
|
|
111
|
-
| `widgetScriptUrl` | `string` | ❌ | - | URL to the chat widget script (loads dynamically) |
|
|
112
|
-
| `accessToken` | `string` | ❌ | - | Optional access token for authenticated requests |
|
|
113
|
-
| `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | ❌ | `'bottom-right'` | Widget position on screen |
|
|
114
|
-
| `backgroundColor` | `string` | ❌ | `'#6366f1'` | Widget background color |
|
|
115
|
-
| `foregroundColor` | `string` | ❌ | `'#ffffff'` | Widget foreground/text color |
|
|
116
|
-
| `size` | `'small' \| 'medium' \| 'large'` | ❌ | `'medium'` | Widget size |
|
|
117
|
-
| `borderWidth` | `number` | ❌ | `2` | Widget border width in pixels |
|
|
118
|
-
| `borderColor` | `string` | ❌ | `'#4f46e5'` | Widget border color |
|
|
119
|
-
| `autoPopup` | `boolean` | ❌ | `false` | Auto popup the chat widget on load |
|
|
120
|
-
| `onAuthSuccess` | `(authData: BridgeAuthResponse) => void` | ❌ | - | Callback when auth bridge succeeds |
|
|
121
|
-
| `onAuthError` | `(error: Error) => void` | ❌ | - | Callback when auth bridge fails |
|
|
122
|
-
| `bridgeAuthEndpoint` | `string` | ❌ | `/api/bridge-auth` | Custom API endpoint path |
|
|
123
|
-
| `containerId` | `string` | ❌ | `bgc-chat-container` | Container element ID |
|
|
124
|
-
|
|
125
|
-
### BridgeAuthResponse
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
interface BridgeAuthResponse {
|
|
129
|
-
cart_context: string | null;
|
|
130
|
-
identity: string | null;
|
|
131
|
-
raw?: string | null;
|
|
132
|
-
}
|
|
133
|
-
```
|
|
51
|
+
## Suggestions for a good README
|
|
134
52
|
|
|
135
|
-
|
|
53
|
+
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
|
|
136
54
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
│ ChatComponent │ ──▶ │ /api/bridge-auth │ ──▶ │ Chat Widget │
|
|
140
|
-
│ (Client) │ │ (Server) │ │ (BridgeChat) │
|
|
141
|
-
└─────────────────┘ └──────────────────┘ └─────────────────┘
|
|
142
|
-
│ │ │
|
|
143
|
-
│ 1. Fetch cookies │ │
|
|
144
|
-
│ ──────────────────────▶│ │
|
|
145
|
-
│ │ Server can read │
|
|
146
|
-
│ │ HttpOnly cookies │
|
|
147
|
-
│ │ │
|
|
148
|
-
│ 2. Return JSON │ │
|
|
149
|
-
│ ◀──────────────────────│ │
|
|
150
|
-
│ │ │
|
|
151
|
-
│ 3. Initialize with cookies + config │
|
|
152
|
-
│ ────────────────────────────────────────────────▶│
|
|
153
|
-
│ │ │
|
|
154
|
-
```
|
|
55
|
+
## Name
|
|
56
|
+
Choose a self-explaining name for your project.
|
|
155
57
|
|
|
156
|
-
##
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
autoPopup: false
|
|
177
|
-
});
|
|
178
|
-
```
|
|
58
|
+
## Description
|
|
59
|
+
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
|
|
60
|
+
|
|
61
|
+
## Badges
|
|
62
|
+
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
|
|
63
|
+
|
|
64
|
+
## Visuals
|
|
65
|
+
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
|
|
69
|
+
|
|
70
|
+
## Usage
|
|
71
|
+
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
|
|
72
|
+
|
|
73
|
+
## Support
|
|
74
|
+
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
|
|
75
|
+
|
|
76
|
+
## Roadmap
|
|
77
|
+
If you have ideas for releases in the future, it is a good idea to list them in the README.
|
|
179
78
|
|
|
180
|
-
##
|
|
79
|
+
## Contributing
|
|
80
|
+
State if you are open to contributions and what your requirements are for accepting them.
|
|
181
81
|
|
|
182
|
-
|
|
183
|
-
- Cookies are passed to the chat widget via JavaScript, not exposed to third parties
|
|
184
|
-
- The component uses `credentials: 'include'` to ensure cookies are sent with the request
|
|
82
|
+
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
|
|
185
83
|
|
|
186
|
-
|
|
84
|
+
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
|
|
187
85
|
|
|
188
|
-
|
|
189
|
-
|
|
86
|
+
## Authors and acknowledgment
|
|
87
|
+
Show your appreciation to those who have contributed to the project.
|
|
190
88
|
|
|
191
89
|
## License
|
|
90
|
+
For open source projects, say how it is licensed.
|
|
192
91
|
|
|
193
|
-
|
|
92
|
+
## Project status
|
|
93
|
+
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
|
package/bin/cli.js
CHANGED
|
@@ -146,8 +146,9 @@ function createFiles(cwd) {
|
|
|
146
146
|
console.log(' 3. Include it in your layout:');
|
|
147
147
|
console.log(` ${colors.yellow}<ChatComponent tenantId="your-tenant-uuid" />${colors.reset}`);
|
|
148
148
|
console.log('\n');
|
|
149
|
-
console.log(' 4.
|
|
150
|
-
console.log(
|
|
149
|
+
console.log(' 4. The bridge-auth route automatically creates a cart context');
|
|
150
|
+
console.log(' if one doesn\'t exist (using the Litium CreateCart mutation).');
|
|
151
|
+
console.log(` It uses ${colors.yellow}RUNTIME_LITIUM_SERVER_URL${colors.reset} env var for the Litium backend URL.`);
|
|
151
152
|
console.log('\n');
|
|
152
153
|
log.success('Setup complete! 🎉');
|
|
153
154
|
console.log('\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatComponent.d.ts","sourceRoot":"","sources":["../../src/ChatComponent.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"ChatComponent.d.ts","sourceRoot":"","sources":["../../src/ChatComponent.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,SAAS,CAAC;AAuCtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAwOtD,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -4,6 +4,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.ChatComponent = void 0;
|
|
5
5
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
6
|
const react_1 = require("react");
|
|
7
|
+
/**
|
|
8
|
+
* Attempt client-side cart creation using the provided getCartFunction,
|
|
9
|
+
* then re-fetch bridge-auth to pick up the newly created cart-context cookie.
|
|
10
|
+
*/
|
|
11
|
+
async function tryClientCartCreation(bridgeAuthEndpoint, getCartFunction, currentAuthData) {
|
|
12
|
+
try {
|
|
13
|
+
await getCartFunction();
|
|
14
|
+
console.log('[ecom-package] getCartFunction completed. Re-fetching bridge auth...');
|
|
15
|
+
const retryRes = await fetch(bridgeAuthEndpoint, {
|
|
16
|
+
method: 'GET',
|
|
17
|
+
credentials: 'include',
|
|
18
|
+
});
|
|
19
|
+
if (!retryRes.ok) {
|
|
20
|
+
console.warn('[ecom-package] Bridge auth retry failed:', retryRes.status);
|
|
21
|
+
return currentAuthData;
|
|
22
|
+
}
|
|
23
|
+
const retryData = await retryRes.json();
|
|
24
|
+
if (retryData.cart_context) {
|
|
25
|
+
console.log('[ecom-package] cart-context obtained after client-side creation.');
|
|
26
|
+
return retryData;
|
|
27
|
+
}
|
|
28
|
+
console.warn('[ecom-package] cart-context still missing after client-side creation.');
|
|
29
|
+
return currentAuthData;
|
|
30
|
+
}
|
|
31
|
+
catch (cartError) {
|
|
32
|
+
console.warn('[ecom-package] Client-side cart creation failed:', cartError);
|
|
33
|
+
return currentAuthData;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
7
36
|
/**
|
|
8
37
|
* ChatComponent - Bridge Chat Widget Integration for Next.js
|
|
9
38
|
*
|
|
@@ -36,7 +65,7 @@ const react_1 = require("react");
|
|
|
36
65
|
*/
|
|
37
66
|
const ChatComponent = ({ tenantId, onAuthSuccess, onAuthError, bridgeAuthEndpoint = '/api/bridge-auth', containerId = 'bgc-chat-container',
|
|
38
67
|
// Widget configuration options
|
|
39
|
-
position = 'bottom-right', backgroundColor = '#6366f1', foregroundColor = '#ffffff', size = 'medium', borderWidth = 2, borderColor = '#4f46e5', autoPopup = false, widgetScriptUrl, identity, cartContext }) => {
|
|
68
|
+
position = 'bottom-right', backgroundColor = '#6366f1', foregroundColor = '#ffffff', size = 'medium', borderWidth = 2, borderColor = '#4f46e5', autoPopup = false, widgetScriptUrl, identity, cartContext, cartCreationMode = 'server', getCartFunction }) => {
|
|
40
69
|
const [isInitialized, setIsInitialized] = (0, react_1.useState)(false);
|
|
41
70
|
const [error, setError] = (0, react_1.useState)(null);
|
|
42
71
|
const [scriptLoaded, setScriptLoaded] = (0, react_1.useState)(false);
|
|
@@ -87,7 +116,10 @@ position = 'bottom-right', backgroundColor = '#6366f1', foregroundColor = '#ffff
|
|
|
87
116
|
}
|
|
88
117
|
else {
|
|
89
118
|
// 1. Call our local Next.js bridge route to get secure cookies
|
|
119
|
+
// In 'server' mode (default), the bridge-auth route automatically
|
|
120
|
+
// creates a cart if cart-context is missing — no client-side retry needed.
|
|
90
121
|
console.log('[ecom-package] Fetching bridge auth from:', bridgeAuthEndpoint);
|
|
122
|
+
console.log('[ecom-package] Cart creation mode:', cartCreationMode);
|
|
91
123
|
const authRes = await fetch(bridgeAuthEndpoint, {
|
|
92
124
|
method: 'GET',
|
|
93
125
|
credentials: 'include', // Important: include cookies in the request
|
|
@@ -97,6 +129,46 @@ position = 'bottom-right', backgroundColor = '#6366f1', foregroundColor = '#ffff
|
|
|
97
129
|
}
|
|
98
130
|
authData = await authRes.json();
|
|
99
131
|
console.log('[ecom-package] Bridge auth response:', authData);
|
|
132
|
+
// 2. Handle missing cart-context based on cartCreationMode
|
|
133
|
+
if (authData.cart_context_missing) {
|
|
134
|
+
if (cartCreationMode === 'server') {
|
|
135
|
+
// In server mode, the bridge-auth route should have created
|
|
136
|
+
// the cart already. If it still reports missing, log a warning.
|
|
137
|
+
// Fall back to client-side if getCartFunction is available.
|
|
138
|
+
console.warn('[ecom-package] Server-side cart creation did not produce a cart-context.');
|
|
139
|
+
if (getCartFunction) {
|
|
140
|
+
console.log('[ecom-package] Falling back to client-side cart creation...');
|
|
141
|
+
authData = await tryClientCartCreation(bridgeAuthEndpoint, getCartFunction, authData);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
console.warn('[ecom-package] No getCartFunction fallback. Proceeding without cart context.');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else if (cartCreationMode === 'client' && getCartFunction) {
|
|
148
|
+
// Client mode: use the provided getCartFunction
|
|
149
|
+
console.log('[ecom-package] Client-side cart creation mode. Triggering getCartFunction...');
|
|
150
|
+
authData = await tryClientCartCreation(bridgeAuthEndpoint, getCartFunction, authData);
|
|
151
|
+
}
|
|
152
|
+
else if (cartCreationMode === 'none') {
|
|
153
|
+
console.log('[ecom-package] Cart creation mode is "none". Proceeding without cart context.');
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
console.warn('[ecom-package] cart-context missing. Mode:', cartCreationMode, getCartFunction ? '(getCartFunction available)' : '(no getCartFunction)');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// 3. Persist the cart context as a client-accessible cookie
|
|
161
|
+
// The Litium proxy may strip Set-Cookie headers from API responses,
|
|
162
|
+
// so we persist a fallback "bridge-cart-context" cookie via JavaScript.
|
|
163
|
+
// The bridge-auth route checks both "cart-context" and "bridge-cart-context".
|
|
164
|
+
if (authData.cart_context) {
|
|
165
|
+
try {
|
|
166
|
+
document.cookie = `bridge-cart-context=${authData.cart_context}; path=/; max-age=${60 * 60 * 24 * 7}; SameSite=Lax`;
|
|
167
|
+
console.log('[ecom-package] Persisted bridge-cart-context cookie');
|
|
168
|
+
}
|
|
169
|
+
catch (cookieErr) {
|
|
170
|
+
console.warn('[ecom-package] Failed to persist cart context cookie:', cookieErr);
|
|
171
|
+
}
|
|
100
172
|
}
|
|
101
173
|
// 2. Wait for BridgeChat to be available (with timeout)
|
|
102
174
|
// 2. Wait for BridgeChat to be available (with timeout)
|
|
@@ -171,7 +243,9 @@ position = 'bottom-right', backgroundColor = '#6366f1', foregroundColor = '#ffff
|
|
|
171
243
|
borderColor,
|
|
172
244
|
autoPopup,
|
|
173
245
|
onAuthSuccess,
|
|
174
|
-
onAuthError
|
|
246
|
+
onAuthError,
|
|
247
|
+
cartCreationMode,
|
|
248
|
+
getCartFunction
|
|
175
249
|
]);
|
|
176
250
|
(0, react_1.useEffect)(() => {
|
|
177
251
|
initChat();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatComponent.js","sourceRoot":"","sources":["../../src/ChatComponent.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;AAEb,iCAAgE;AAGhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACI,MAAM,aAAa,GAAiC,CAAC,EACxD,QAAQ,EACR,aAAa,EACb,WAAW,EACX,kBAAkB,GAAG,kBAAkB,EACvC,WAAW,GAAG,oBAAoB;AAClC,+BAA+B;AAC/B,QAAQ,GAAG,cAAc,EACzB,eAAe,GAAG,SAAS,EAC3B,eAAe,GAAG,SAAS,EAC3B,IAAI,GAAG,QAAQ,EACf,WAAW,GAAG,CAAC,EACf,WAAW,GAAG,SAAS,EACvB,SAAS,GAAG,KAAK,EACjB,eAAe,EACf,QAAQ,EACR,WAAW,
|
|
1
|
+
{"version":3,"file":"ChatComponent.js","sourceRoot":"","sources":["../../src/ChatComponent.tsx"],"names":[],"mappings":"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"}
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -43,15 +43,41 @@ export interface ChatComponentProps {
|
|
|
43
43
|
identity?: string;
|
|
44
44
|
/** Optional cart context token to skip internal API call */
|
|
45
45
|
cartContext?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Controls how cart context is created when the cart-context cookie is missing.
|
|
48
|
+
*
|
|
49
|
+
* - `'server'` (default): The bridge-auth API route handles cart creation
|
|
50
|
+
* server-side using the Litium CreateCart mutation. No additional props needed.
|
|
51
|
+
* - `'client'`: Falls back to calling `getCartFunction` on the client side,
|
|
52
|
+
* then retries bridge-auth. Requires `getCartFunction` prop.
|
|
53
|
+
* - `'none'`: No automatic cart creation. The widget initializes without
|
|
54
|
+
* a cart context if the cookie is missing.
|
|
55
|
+
*/
|
|
56
|
+
cartCreationMode?: 'server' | 'client' | 'none';
|
|
57
|
+
/**
|
|
58
|
+
* Optional function to call getCart from the client side.
|
|
59
|
+
* Used as a fallback when `cartCreationMode` is `'client'`, or when
|
|
60
|
+
* server-side cart creation (the default) fails.
|
|
61
|
+
*
|
|
62
|
+
* When cart-context cookie is missing, this function will be called
|
|
63
|
+
* to trigger cart creation (which sets the cookie), then bridge-auth
|
|
64
|
+
* is re-fetched to pick up the newly created cookie.
|
|
65
|
+
*
|
|
66
|
+
* Example: import { get as getCart } from 'services/cartService.client';
|
|
67
|
+
* <ChatComponent getCartFunction={getCart} cartCreationMode="client" />
|
|
68
|
+
*/
|
|
69
|
+
getCartFunction?: () => Promise<any>;
|
|
46
70
|
}
|
|
47
71
|
/**
|
|
48
72
|
* Response from the bridge-auth API route
|
|
49
73
|
*/
|
|
50
74
|
export interface BridgeAuthResponse {
|
|
51
|
-
/** The cart context cookie value
|
|
75
|
+
/** The cart context cookie value */
|
|
52
76
|
cart_context?: string | null;
|
|
53
77
|
/** The ASP.NET Core Identity cookie value */
|
|
54
78
|
identity: string | null;
|
|
79
|
+
/** Whether the cart-context cookie was missing from the request */
|
|
80
|
+
cart_context_missing?: boolean;
|
|
55
81
|
/** Raw cookie header string (optional, for debugging) */
|
|
56
82
|
raw?: string | null;
|
|
57
83
|
}
|
package/dist/cjs/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAC;AAEvF;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IAEjB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAEvD,yDAAyD;IACzD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAErC,yFAAyF;IACzF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAC;IAIrB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,cAAc,CAAC;IAE1B,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,wDAAwD;IACxD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,sCAAsC;IACtC,IAAI,CAAC,EAAE,UAAU,CAAC;IAElB,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,4DAA4D;IAC5D,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,35 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useState, useCallback } from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* Attempt client-side cart creation using the provided getCartFunction,
|
|
6
|
+
* then re-fetch bridge-auth to pick up the newly created cart-context cookie.
|
|
7
|
+
*/
|
|
8
|
+
async function tryClientCartCreation(bridgeAuthEndpoint, getCartFunction, currentAuthData) {
|
|
9
|
+
try {
|
|
10
|
+
await getCartFunction();
|
|
11
|
+
console.log('[ecom-package] getCartFunction completed. Re-fetching bridge auth...');
|
|
12
|
+
const retryRes = await fetch(bridgeAuthEndpoint, {
|
|
13
|
+
method: 'GET',
|
|
14
|
+
credentials: 'include',
|
|
15
|
+
});
|
|
16
|
+
if (!retryRes.ok) {
|
|
17
|
+
console.warn('[ecom-package] Bridge auth retry failed:', retryRes.status);
|
|
18
|
+
return currentAuthData;
|
|
19
|
+
}
|
|
20
|
+
const retryData = await retryRes.json();
|
|
21
|
+
if (retryData.cart_context) {
|
|
22
|
+
console.log('[ecom-package] cart-context obtained after client-side creation.');
|
|
23
|
+
return retryData;
|
|
24
|
+
}
|
|
25
|
+
console.warn('[ecom-package] cart-context still missing after client-side creation.');
|
|
26
|
+
return currentAuthData;
|
|
27
|
+
}
|
|
28
|
+
catch (cartError) {
|
|
29
|
+
console.warn('[ecom-package] Client-side cart creation failed:', cartError);
|
|
30
|
+
return currentAuthData;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
4
33
|
/**
|
|
5
34
|
* ChatComponent - Bridge Chat Widget Integration for Next.js
|
|
6
35
|
*
|
|
@@ -33,7 +62,7 @@ import { useEffect, useState, useCallback } from 'react';
|
|
|
33
62
|
*/
|
|
34
63
|
export const ChatComponent = ({ tenantId, onAuthSuccess, onAuthError, bridgeAuthEndpoint = '/api/bridge-auth', containerId = 'bgc-chat-container',
|
|
35
64
|
// Widget configuration options
|
|
36
|
-
position = 'bottom-right', backgroundColor = '#6366f1', foregroundColor = '#ffffff', size = 'medium', borderWidth = 2, borderColor = '#4f46e5', autoPopup = false, widgetScriptUrl, identity, cartContext }) => {
|
|
65
|
+
position = 'bottom-right', backgroundColor = '#6366f1', foregroundColor = '#ffffff', size = 'medium', borderWidth = 2, borderColor = '#4f46e5', autoPopup = false, widgetScriptUrl, identity, cartContext, cartCreationMode = 'server', getCartFunction }) => {
|
|
37
66
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
38
67
|
const [error, setError] = useState(null);
|
|
39
68
|
const [scriptLoaded, setScriptLoaded] = useState(false);
|
|
@@ -84,7 +113,10 @@ position = 'bottom-right', backgroundColor = '#6366f1', foregroundColor = '#ffff
|
|
|
84
113
|
}
|
|
85
114
|
else {
|
|
86
115
|
// 1. Call our local Next.js bridge route to get secure cookies
|
|
116
|
+
// In 'server' mode (default), the bridge-auth route automatically
|
|
117
|
+
// creates a cart if cart-context is missing — no client-side retry needed.
|
|
87
118
|
console.log('[ecom-package] Fetching bridge auth from:', bridgeAuthEndpoint);
|
|
119
|
+
console.log('[ecom-package] Cart creation mode:', cartCreationMode);
|
|
88
120
|
const authRes = await fetch(bridgeAuthEndpoint, {
|
|
89
121
|
method: 'GET',
|
|
90
122
|
credentials: 'include', // Important: include cookies in the request
|
|
@@ -94,6 +126,46 @@ position = 'bottom-right', backgroundColor = '#6366f1', foregroundColor = '#ffff
|
|
|
94
126
|
}
|
|
95
127
|
authData = await authRes.json();
|
|
96
128
|
console.log('[ecom-package] Bridge auth response:', authData);
|
|
129
|
+
// 2. Handle missing cart-context based on cartCreationMode
|
|
130
|
+
if (authData.cart_context_missing) {
|
|
131
|
+
if (cartCreationMode === 'server') {
|
|
132
|
+
// In server mode, the bridge-auth route should have created
|
|
133
|
+
// the cart already. If it still reports missing, log a warning.
|
|
134
|
+
// Fall back to client-side if getCartFunction is available.
|
|
135
|
+
console.warn('[ecom-package] Server-side cart creation did not produce a cart-context.');
|
|
136
|
+
if (getCartFunction) {
|
|
137
|
+
console.log('[ecom-package] Falling back to client-side cart creation...');
|
|
138
|
+
authData = await tryClientCartCreation(bridgeAuthEndpoint, getCartFunction, authData);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
console.warn('[ecom-package] No getCartFunction fallback. Proceeding without cart context.');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else if (cartCreationMode === 'client' && getCartFunction) {
|
|
145
|
+
// Client mode: use the provided getCartFunction
|
|
146
|
+
console.log('[ecom-package] Client-side cart creation mode. Triggering getCartFunction...');
|
|
147
|
+
authData = await tryClientCartCreation(bridgeAuthEndpoint, getCartFunction, authData);
|
|
148
|
+
}
|
|
149
|
+
else if (cartCreationMode === 'none') {
|
|
150
|
+
console.log('[ecom-package] Cart creation mode is "none". Proceeding without cart context.');
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
console.warn('[ecom-package] cart-context missing. Mode:', cartCreationMode, getCartFunction ? '(getCartFunction available)' : '(no getCartFunction)');
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// 3. Persist the cart context as a client-accessible cookie
|
|
158
|
+
// The Litium proxy may strip Set-Cookie headers from API responses,
|
|
159
|
+
// so we persist a fallback "bridge-cart-context" cookie via JavaScript.
|
|
160
|
+
// The bridge-auth route checks both "cart-context" and "bridge-cart-context".
|
|
161
|
+
if (authData.cart_context) {
|
|
162
|
+
try {
|
|
163
|
+
document.cookie = `bridge-cart-context=${authData.cart_context}; path=/; max-age=${60 * 60 * 24 * 7}; SameSite=Lax`;
|
|
164
|
+
console.log('[ecom-package] Persisted bridge-cart-context cookie');
|
|
165
|
+
}
|
|
166
|
+
catch (cookieErr) {
|
|
167
|
+
console.warn('[ecom-package] Failed to persist cart context cookie:', cookieErr);
|
|
168
|
+
}
|
|
97
169
|
}
|
|
98
170
|
// 2. Wait for BridgeChat to be available (with timeout)
|
|
99
171
|
// 2. Wait for BridgeChat to be available (with timeout)
|
|
@@ -168,7 +240,9 @@ position = 'bottom-right', backgroundColor = '#6366f1', foregroundColor = '#ffff
|
|
|
168
240
|
borderColor,
|
|
169
241
|
autoPopup,
|
|
170
242
|
onAuthSuccess,
|
|
171
|
-
onAuthError
|
|
243
|
+
onAuthError,
|
|
244
|
+
cartCreationMode,
|
|
245
|
+
getCartFunction
|
|
172
246
|
]);
|
|
173
247
|
useEffect(() => {
|
|
174
248
|
initChat();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatComponent.js","sourceRoot":"","sources":["../../src/ChatComponent.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAGhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,MAAM,aAAa,GAAiC,CAAC,EACxD,QAAQ,EACR,aAAa,EACb,WAAW,EACX,kBAAkB,GAAG,kBAAkB,EACvC,WAAW,GAAG,oBAAoB;AAClC,+BAA+B;AAC/B,QAAQ,GAAG,cAAc,EACzB,eAAe,GAAG,SAAS,EAC3B,eAAe,GAAG,SAAS,EAC3B,IAAI,GAAG,QAAQ,EACf,WAAW,GAAG,CAAC,EACf,WAAW,GAAG,SAAS,EACvB,SAAS,GAAG,KAAK,EACjB,eAAe,EACf,QAAQ,EACR,WAAW,
|
|
1
|
+
{"version":3,"file":"ChatComponent.js","sourceRoot":"","sources":["../../src/ChatComponent.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bridge-ai-dev/ecom-chat",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "Bridge E-commerce Chat widget integration for Next.js with Litium authentication",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -46,4 +46,4 @@
|
|
|
46
46
|
"type": "git",
|
|
47
47
|
"url": "https://github.com/bridge-ai/ecom-chat.git"
|
|
48
48
|
}
|
|
49
|
-
}
|
|
49
|
+
}
|
|
@@ -1,38 +1,208 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from "next/server";
|
|
2
2
|
|
|
3
|
+
const CREATE_CART_MUTATION = `
|
|
4
|
+
mutation CreateCart {
|
|
5
|
+
createCart {
|
|
6
|
+
cart {
|
|
7
|
+
__typename
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
`;
|
|
12
|
+
|
|
3
13
|
/**
|
|
4
|
-
*
|
|
14
|
+
* Constructs the GraphQL endpoint URL.
|
|
15
|
+
* Uses the same Next.js server so the rewrite rule in next.config.js
|
|
16
|
+
* forwards the request to Litium with proper context.
|
|
5
17
|
*
|
|
18
|
+
* Note: The incoming request.url may show https:// (from the proxy),
|
|
19
|
+
* but the Next.js dev server runs on http://. We force http:// for
|
|
20
|
+
* localhost to avoid SSL errors.
|
|
21
|
+
*/
|
|
22
|
+
function getGraphQLUrl(request: NextRequest): string {
|
|
23
|
+
const url = new URL(request.url);
|
|
24
|
+
// Force http:// for localhost — Next.js dev server doesn't use SSL
|
|
25
|
+
if (url.hostname === 'localhost' || url.hostname === '127.0.0.1') {
|
|
26
|
+
url.protocol = 'http:';
|
|
27
|
+
}
|
|
28
|
+
return `${url.origin}/storefront.graphql`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Parse a single Set-Cookie header string into a cookie object.
|
|
33
|
+
*/
|
|
34
|
+
function parseSetCookieString(cookieStr: string): { name: string; value: string; [k: string]: any } | null {
|
|
35
|
+
const parts = cookieStr.split(';').map(p => p.trim());
|
|
36
|
+
const [nameValue, ...attrs] = parts;
|
|
37
|
+
const eqIdx = nameValue.indexOf('=');
|
|
38
|
+
if (eqIdx === -1) return null;
|
|
39
|
+
|
|
40
|
+
const name = nameValue.substring(0, eqIdx);
|
|
41
|
+
const value = nameValue.substring(eqIdx + 1);
|
|
42
|
+
|
|
43
|
+
const cookieObj: any = { name, value };
|
|
44
|
+
for (const attr of attrs) {
|
|
45
|
+
const [aKey, ...aValParts] = attr.split('=');
|
|
46
|
+
const aKeyLower = aKey.toLowerCase().trim();
|
|
47
|
+
const aVal = aValParts.join('=').trim();
|
|
48
|
+
|
|
49
|
+
if (aKeyLower === 'path') cookieObj.path = aVal || '/';
|
|
50
|
+
if (aKeyLower === 'max-age') cookieObj.maxAge = parseInt(aVal, 10);
|
|
51
|
+
if (aKeyLower === 'httponly') cookieObj.httpOnly = true;
|
|
52
|
+
if (aKeyLower === 'secure') cookieObj.secure = true;
|
|
53
|
+
if (aKeyLower === 'samesite') cookieObj.sameSite = aVal.toLowerCase();
|
|
54
|
+
if (aKeyLower === 'domain') cookieObj.domain = aVal;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return cookieObj;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Bridge Auth API Route
|
|
62
|
+
*
|
|
6
63
|
* This route acts as a secure bridge to retrieve HttpOnly cookies
|
|
7
64
|
* that cannot be accessed from client-side JavaScript.
|
|
8
|
-
*
|
|
65
|
+
*
|
|
9
66
|
* The ChatComponent uses this route to get authentication context
|
|
10
67
|
* before initializing the chat widget.
|
|
68
|
+
*
|
|
69
|
+
* If the cart-context cookie is missing, this route will automatically
|
|
70
|
+
* create a new cart by calling the Litium CreateCart mutation server-side,
|
|
71
|
+
* and forward the resulting Set-Cookie headers to the browser.
|
|
11
72
|
*/
|
|
12
73
|
export const GET = async (request: NextRequest) => {
|
|
13
74
|
const cookies = request.cookies;
|
|
14
75
|
|
|
15
|
-
// Debug: Log all available cookie names
|
|
16
|
-
const allCookieNames = cookies.getAll().map(c => c.name);
|
|
17
|
-
console.log('[bridge-auth] All cookie names:', allCookieNames);
|
|
18
76
|
console.log('[bridge-auth] Raw cookie header:', request.headers.get("cookie"));
|
|
19
|
-
|
|
77
|
+
|
|
20
78
|
// Retrieve the secure cookies
|
|
21
79
|
const identity = cookies.get(".AspNetCore.Identity.Application")?.value;
|
|
22
|
-
|
|
80
|
+
// Check native Litium cart-context first, then our fallback bridge-cart-context
|
|
81
|
+
let cartContext = cookies.get("cart-context")?.value
|
|
82
|
+
|| cookies.get("bridge-cart-context")?.value;
|
|
83
|
+
|
|
84
|
+
console.log('[bridge-auth] Identity:', identity ? 'FOUND' : 'NOT FOUND');
|
|
85
|
+
console.log('[bridge-auth] Cart context:', cartContext ? 'FOUND' : 'NOT FOUND',
|
|
86
|
+
cartContext ? `(from: ${cookies.get("cart-context")?.value ? 'cart-context' : 'bridge-cart-context'})` : '');
|
|
23
87
|
|
|
24
|
-
|
|
25
|
-
console.log('[bridge-auth] Identity cookie value:', identity ?? 'NOT FOUND');
|
|
26
|
-
console.log('[bridge-auth] Cart context cookie value:', cartContext ?? 'NOT FOUND');
|
|
88
|
+
const responseCookies: Array<{ name: string; value: string; [k: string]: any }> = [];
|
|
27
89
|
|
|
28
|
-
|
|
90
|
+
// If cart-context is missing, create one via the Litium CreateCart mutation
|
|
91
|
+
if (!cartContext) {
|
|
92
|
+
console.log('[bridge-auth] cart-context missing. Creating cart server-side...');
|
|
93
|
+
try {
|
|
94
|
+
const graphqlUrl = getGraphQLUrl(request);
|
|
95
|
+
console.log('[bridge-auth] GraphQL URL:', graphqlUrl);
|
|
96
|
+
|
|
97
|
+
// Determine the storefront context URL for the Litium header.
|
|
98
|
+
// This MUST be the storefront URL (e.g., https://localhost:3001/),
|
|
99
|
+
// NOT the Litium backend URL. Litium uses this to resolve the channel/website.
|
|
100
|
+
const refererUrl = request.headers.get('referer');
|
|
101
|
+
const originUrl = request.headers.get('origin');
|
|
102
|
+
const storefrontContextUrl = refererUrl || originUrl || new URL(request.url).origin;
|
|
103
|
+
console.log('[bridge-auth] Context URL:', storefrontContextUrl,
|
|
104
|
+
'(from:', refererUrl ? 'referer' : originUrl ? 'origin' : 'request.url', ')');
|
|
105
|
+
|
|
106
|
+
const gqlRes = await fetch(graphqlUrl, {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
headers: {
|
|
109
|
+
'Content-Type': 'application/json',
|
|
110
|
+
// Critical: Litium requires this to know which storefront context to use
|
|
111
|
+
'x-litium-storefront-context-url': storefrontContextUrl,
|
|
112
|
+
// Forward the browser's cookies to Litium so it can associate
|
|
113
|
+
// the new cart with any existing session/identity
|
|
114
|
+
...(request.headers.get('cookie')
|
|
115
|
+
? { 'Cookie': request.headers.get('cookie')! }
|
|
116
|
+
: {}),
|
|
117
|
+
},
|
|
118
|
+
body: JSON.stringify({ query: CREATE_CART_MUTATION }),
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
console.log('[bridge-auth] CreateCart response status:', gqlRes.status);
|
|
122
|
+
|
|
123
|
+
// Log all response headers for debugging
|
|
124
|
+
const allHeaders: Record<string, string> = {};
|
|
125
|
+
gqlRes.headers.forEach((value, key) => {
|
|
126
|
+
allHeaders[key] = key.toLowerCase() === 'set-cookie' ? value : value.substring(0, 100);
|
|
127
|
+
});
|
|
128
|
+
console.log('[bridge-auth] Response headers:', JSON.stringify(allHeaders));
|
|
129
|
+
|
|
130
|
+
if (gqlRes.ok) {
|
|
131
|
+
// Log the response body for debugging
|
|
132
|
+
const responseBody = await gqlRes.text();
|
|
133
|
+
console.log('[bridge-auth] CreateCart response body:', responseBody.substring(0, 500));
|
|
134
|
+
|
|
135
|
+
// Extract Set-Cookie headers from Litium's response
|
|
136
|
+
// Use getSetCookie() (standard) with fallback to get('set-cookie')
|
|
137
|
+
const setCookieHeaders: string[] = gqlRes.headers.getSetCookie?.()
|
|
138
|
+
?? (gqlRes.headers.get('set-cookie')?.split(',')
|
|
139
|
+
.map((s: string) => s.trim())
|
|
140
|
+
.filter(Boolean) as string[] ?? []);
|
|
141
|
+
|
|
142
|
+
console.log('[bridge-auth] Set-Cookie headers count:', setCookieHeaders.length);
|
|
143
|
+
if (setCookieHeaders.length > 0) {
|
|
144
|
+
console.log('[bridge-auth] Set-Cookie values:', setCookieHeaders.map(s => s.substring(0, 80)));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
for (const cookieStr of setCookieHeaders) {
|
|
148
|
+
const parsed = parseSetCookieString(cookieStr);
|
|
149
|
+
if (!parsed) continue;
|
|
150
|
+
|
|
151
|
+
responseCookies.push(parsed);
|
|
152
|
+
|
|
153
|
+
// Check if this is the cart-context cookie we need
|
|
154
|
+
if (parsed.name === 'cart-context') {
|
|
155
|
+
cartContext = parsed.value;
|
|
156
|
+
console.log('[bridge-auth] Cart context created successfully');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Also check for cart context in the GraphQL extensions
|
|
161
|
+
// Litium may return the cart context in the extensions field instead of Set-Cookie
|
|
162
|
+
try {
|
|
163
|
+
const jsonBody = JSON.parse(responseBody);
|
|
164
|
+
const extensionCartContext = jsonBody?.extensions?.['x-litium-storefront-cart-context'];
|
|
165
|
+
if (extensionCartContext && !cartContext) {
|
|
166
|
+
cartContext = extensionCartContext;
|
|
167
|
+
console.log('[bridge-auth] Cart context obtained from extensions field');
|
|
168
|
+
}
|
|
169
|
+
} catch (parseErr) {
|
|
170
|
+
// Ignore parse errors
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (!cartContext) {
|
|
174
|
+
console.warn('[bridge-auth] CreateCart succeeded but no cart-context in response');
|
|
175
|
+
}
|
|
176
|
+
} else {
|
|
177
|
+
const errorText = await gqlRes.text().catch(() => 'unknown');
|
|
178
|
+
console.error('[bridge-auth] CreateCart mutation failed:', gqlRes.status, errorText);
|
|
179
|
+
}
|
|
180
|
+
} catch (err) {
|
|
181
|
+
console.error('[bridge-auth] Error creating cart:', err);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const jsonBody = {
|
|
29
186
|
identity: identity || null,
|
|
30
187
|
cart_context: cartContext || null,
|
|
31
|
-
|
|
32
|
-
raw: request.headers.get("cookie")
|
|
188
|
+
cart_context_missing: !cartContext,
|
|
189
|
+
raw: request.headers.get("cookie"),
|
|
33
190
|
};
|
|
34
191
|
|
|
35
|
-
console.log('[bridge-auth]
|
|
192
|
+
console.log('[bridge-auth] Response:', JSON.stringify({
|
|
193
|
+
identity: jsonBody.identity ? '[present]' : null,
|
|
194
|
+
cart_context: jsonBody.cart_context ? '[present]' : null,
|
|
195
|
+
cart_context_missing: jsonBody.cart_context_missing,
|
|
196
|
+
}));
|
|
197
|
+
|
|
198
|
+
const response = NextResponse.json(jsonBody);
|
|
199
|
+
|
|
200
|
+
// Forward Litium's Set-Cookie headers to the browser so
|
|
201
|
+
// the cart-context cookie is persisted for subsequent requests
|
|
202
|
+
for (const cookie of responseCookies) {
|
|
203
|
+
const { name, value, ...options } = cookie;
|
|
204
|
+
response.cookies.set(name, value, options);
|
|
205
|
+
}
|
|
36
206
|
|
|
37
|
-
return
|
|
207
|
+
return response;
|
|
38
208
|
};
|