@bridge-ai-dev/ecom-chat 1.0.9 → 1.0.11
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 +53 -70
- package/bin/cli.js +53 -26
- package/dist/cjs/ChatComponent.d.ts.map +1 -1
- package/dist/cjs/ChatComponent.js +67 -31
- package/dist/cjs/ChatComponent.js.map +1 -1
- package/dist/cjs/types.d.ts +15 -1
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/ChatComponent.js +67 -31
- package/dist/esm/ChatComponent.js.map +1 -1
- package/package.json +1 -1
- package/templates/ChatWrapper.tsx.template +19 -0
- package/templates/route.ts.template +182 -23
package/README.md
CHANGED
|
@@ -1,93 +1,76 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Bridge E-commerce Chat widget integration for Next.js
|
|
2
2
|
|
|
3
|
+
A powerful chat widget integration specifically designed for Next.js and Litium storefronts. It handles complex authentication flows and automatic cart context initialization.
|
|
3
4
|
|
|
5
|
+
## Features
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
- **Automatic Cart Scaling**: Server-side cart creation using Litium's `CreateCart` mutation.
|
|
8
|
+
- **Secure Auth Bridge**: Handles HttpOnly cookies (`.AspNetCore.Identity.Application` and `cart-context`) safely.
|
|
9
|
+
- **Next.js Optimized**: Built for the App Router and React Server Components.
|
|
10
|
+
- **Zero Configuration**: Scaffolding tool to get you started in seconds.
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
## Quick Start
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
Run the following command in your Next.js project root:
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
|
|
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:
|
|
15
|
-
|
|
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
|
|
16
|
+
```bash
|
|
17
|
+
npx @bridge-ai-dev/ecom-chat
|
|
21
18
|
```
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
## Collaborate with your team
|
|
28
|
-
|
|
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/)
|
|
34
|
-
|
|
35
|
-
## Test and Deploy
|
|
36
|
-
|
|
37
|
-
Use the built-in continuous integration in GitLab.
|
|
38
|
-
|
|
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)
|
|
20
|
+
This will:
|
|
21
|
+
1. Create `app/api/bridge-auth/route.ts` (The secure auth bridge)
|
|
22
|
+
2. Create `components/ChatWrapper.tsx` (A pre-configured component wrapper)
|
|
44
23
|
|
|
45
|
-
|
|
24
|
+
## Configuration
|
|
46
25
|
|
|
47
|
-
|
|
26
|
+
Add the following environment variables to your `.env.local`:
|
|
48
27
|
|
|
49
|
-
|
|
28
|
+
```env
|
|
29
|
+
# Required for the Widget
|
|
30
|
+
NEXT_PUBLIC_BRIDGE_TENANT_ID=your-tenant-uuid
|
|
31
|
+
NEXT_PUBLIC_BRIDGE_WIDGET_URL=https://...
|
|
50
32
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
## Name
|
|
56
|
-
Choose a self-explaining name for your project.
|
|
57
|
-
|
|
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.
|
|
33
|
+
# Required for server-side cart initialization
|
|
34
|
+
RUNTIME_LITIUM_SERVER_URL=https://your-litium-backend.com
|
|
35
|
+
```
|
|
69
36
|
|
|
70
37
|
## 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
38
|
|
|
73
|
-
|
|
74
|
-
|
|
39
|
+
In your `app/layout.tsx`:
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import ChatWrapper from '@/components/ChatWrapper';
|
|
43
|
+
|
|
44
|
+
export default function RootLayout({ children }) {
|
|
45
|
+
return (
|
|
46
|
+
<html>
|
|
47
|
+
<body>
|
|
48
|
+
{children}
|
|
49
|
+
<ChatWrapper />
|
|
50
|
+
</body>
|
|
51
|
+
</html>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
```
|
|
75
55
|
|
|
76
|
-
##
|
|
77
|
-
If you have ideas for releases in the future, it is a good idea to list them in the README.
|
|
56
|
+
## How it works
|
|
78
57
|
|
|
79
|
-
|
|
80
|
-
|
|
58
|
+
The library uses a "Bridge Auth" pattern:
|
|
59
|
+
1. The **ChatComponent** (client-side) calls the `/api/bridge-auth` route.
|
|
60
|
+
2. The **Auth Route** (server-side) reads the secure Litium cookies.
|
|
61
|
+
3. If the **cart-context** cookie is missing, the route automatically performs a `CreateCart` mutation to Litium's GraphQL API.
|
|
62
|
+
4. The route returns the auth data to the widget and forwards any new `Set-Cookie` headers to the browser.
|
|
81
63
|
|
|
82
|
-
|
|
64
|
+
## Customization
|
|
83
65
|
|
|
84
|
-
|
|
66
|
+
### `ChatComponent` Props
|
|
85
67
|
|
|
86
|
-
|
|
87
|
-
|
|
68
|
+
| Prop | Type | Default | Description |
|
|
69
|
+
|------|------|---------|-------------|
|
|
70
|
+
| `tenantId` | `string` | **Required** | Your Bridge AI tenant ID. |
|
|
71
|
+
| `widgetScriptUrl` | `string` | **Required** | URL of the chat widget script. |
|
|
72
|
+
| `cartCreationMode` | `'server' \| 'client' \| 'none'` | `'server'` | How to handle missing carts. |
|
|
88
73
|
|
|
89
74
|
## License
|
|
90
|
-
For open source projects, say how it is licensed.
|
|
91
75
|
|
|
92
|
-
|
|
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.
|
|
76
|
+
MIT
|
package/bin/cli.js
CHANGED
|
@@ -21,14 +21,19 @@ const log = {
|
|
|
21
21
|
step: (msg) => console.log(`${colors.bold}🚀 ${msg}${colors.reset}`)
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
// Read the
|
|
25
|
-
const
|
|
26
|
-
|
|
24
|
+
// Read the template contents
|
|
25
|
+
const templatesDir = path.join(__dirname, '..', 'templates');
|
|
26
|
+
const routeTemplatePath = path.join(templatesDir, 'route.ts.template');
|
|
27
|
+
const wrapperTemplatePath = path.join(templatesDir, 'ChatWrapper.tsx.template');
|
|
28
|
+
|
|
29
|
+
let routeTemplateContent;
|
|
30
|
+
let wrapperTemplateContent;
|
|
27
31
|
|
|
28
32
|
try {
|
|
29
|
-
|
|
33
|
+
routeTemplateContent = fs.readFileSync(routeTemplatePath, 'utf8');
|
|
34
|
+
wrapperTemplateContent = fs.readFileSync(wrapperTemplatePath, 'utf8');
|
|
30
35
|
} catch (error) {
|
|
31
|
-
console.error(`${colors.red}❌ Error reading template
|
|
36
|
+
console.error(`${colors.red}❌ Error reading template files: ${error.message}${colors.reset}`);
|
|
32
37
|
process.exit(1);
|
|
33
38
|
}
|
|
34
39
|
|
|
@@ -39,9 +44,7 @@ function isNextJsProject(cwd) {
|
|
|
39
44
|
'next.config.mjs',
|
|
40
45
|
'next.config.ts',
|
|
41
46
|
path.join('app', 'layout.tsx'),
|
|
42
|
-
path.join('app', 'layout.
|
|
43
|
-
path.join('app', 'page.tsx'),
|
|
44
|
-
path.join('app', 'page.js')
|
|
47
|
+
path.join('app', 'app', 'layout.tsx')
|
|
45
48
|
];
|
|
46
49
|
|
|
47
50
|
for (const indicator of indicators) {
|
|
@@ -115,41 +118,65 @@ function setup() {
|
|
|
115
118
|
}
|
|
116
119
|
|
|
117
120
|
function createFiles(cwd) {
|
|
118
|
-
|
|
119
|
-
const
|
|
121
|
+
// 1. Create the API Route
|
|
122
|
+
const apiDir = path.join(cwd, 'app', 'api', 'bridge-auth');
|
|
123
|
+
const apiFile = path.join(apiDir, 'route.ts');
|
|
120
124
|
|
|
121
|
-
|
|
122
|
-
if (fs.existsSync(targetFile)) {
|
|
125
|
+
if (fs.existsSync(apiFile)) {
|
|
123
126
|
log.warning('API route already exists at: app/api/bridge-auth/route.ts');
|
|
124
|
-
log.info('Skipping file creation to avoid overwriting.');
|
|
125
127
|
} else {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
fs.mkdirSync(targetDir, { recursive: true });
|
|
128
|
+
if (!fs.existsSync(apiDir)) {
|
|
129
|
+
fs.mkdirSync(apiDir, { recursive: true });
|
|
129
130
|
log.success('Created directory: app/api/bridge-auth/');
|
|
130
131
|
}
|
|
131
|
-
|
|
132
|
-
// Write the API route file
|
|
133
|
-
fs.writeFileSync(targetFile, apiRouteContent, 'utf8');
|
|
132
|
+
fs.writeFileSync(apiFile, routeTemplateContent, 'utf8');
|
|
134
133
|
log.success('Created API route: app/api/bridge-auth/route.ts');
|
|
135
134
|
}
|
|
136
135
|
|
|
136
|
+
// 2. Create the ChatWrapper Component
|
|
137
|
+
// Try to find components directory, fallback to cwd/components
|
|
138
|
+
let componentsDir = path.join(cwd, 'components');
|
|
139
|
+
if (!fs.existsSync(componentsDir)) {
|
|
140
|
+
// Check if there's an src/components
|
|
141
|
+
const srcComponents = path.join(cwd, 'src', 'components');
|
|
142
|
+
if (fs.existsSync(srcComponents)) {
|
|
143
|
+
componentsDir = srcComponents;
|
|
144
|
+
} else {
|
|
145
|
+
// Create a components directory if it doesn't exist
|
|
146
|
+
fs.mkdirSync(componentsDir, { recursive: true });
|
|
147
|
+
log.success('Created directory: components/');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const wrapperFile = path.join(componentsDir, 'ChatWrapper.tsx');
|
|
152
|
+
|
|
153
|
+
if (fs.existsSync(wrapperFile)) {
|
|
154
|
+
log.warning('ChatWrapper already exists at: components/ChatWrapper.tsx');
|
|
155
|
+
} else {
|
|
156
|
+
fs.writeFileSync(wrapperFile, wrapperTemplateContent, 'utf8');
|
|
157
|
+
log.success(`Created ChatWrapper: ${path.relative(cwd, wrapperFile)}`);
|
|
158
|
+
}
|
|
159
|
+
|
|
137
160
|
console.log('\n');
|
|
138
161
|
log.step('Next Steps:');
|
|
139
162
|
console.log('\n');
|
|
140
163
|
console.log(' 1. Install the package (if not already):');
|
|
141
164
|
console.log(` ${colors.yellow}npm install @bridge-ai-dev/ecom-chat${colors.reset}`);
|
|
142
165
|
console.log('\n');
|
|
143
|
-
console.log(' 2. Add
|
|
144
|
-
console.log(` ${colors.yellow}
|
|
166
|
+
console.log(' 2. Add environment variables to your .env.local:');
|
|
167
|
+
console.log(` ${colors.yellow}NEXT_PUBLIC_BRIDGE_TENANT_ID=your-tenant-id${colors.reset}`);
|
|
168
|
+
console.log(` ${colors.yellow}NEXT_PUBLIC_BRIDGE_WIDGET_URL=https://...${colors.reset}`);
|
|
169
|
+
console.log(` ${colors.yellow}RUNTIME_LITIUM_SERVER_URL=https://your-litium-backend.com${colors.reset}`);
|
|
145
170
|
console.log('\n');
|
|
146
|
-
console.log(' 3.
|
|
147
|
-
console.log(` ${colors.yellow}
|
|
171
|
+
console.log(' 3. Use the ChatWrapper in your app/layout.tsx:');
|
|
172
|
+
console.log(` ${colors.yellow}import ChatWrapper from 'components/ChatWrapper';${colors.reset}`);
|
|
173
|
+
console.log(' ...');
|
|
174
|
+
console.log(` ${colors.yellow}<ChatWrapper />${colors.reset}`);
|
|
148
175
|
console.log('\n');
|
|
149
|
-
console.log(' 4.
|
|
150
|
-
console.log(` ${colors.
|
|
176
|
+
console.log(' 4. Verify the bridge-auth route is accessible:');
|
|
177
|
+
console.log(` ${colors.blue}http://localhost:3000/api/bridge-auth${colors.reset}`);
|
|
151
178
|
console.log('\n');
|
|
152
|
-
log.success('
|
|
179
|
+
log.success('Scaffolding complete! 🎉');
|
|
153
180
|
console.log('\n');
|
|
154
181
|
}
|
|
155
182
|
|
|
@@ -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, getCartFunction }) => {
|
|
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,42 +129,45 @@ 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);
|
|
100
|
-
// 2.
|
|
101
|
-
if (authData.cart_context_missing
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
});
|
|
111
|
-
if (!retryRes.ok) {
|
|
112
|
-
console.warn('[ecom-package] Bridge auth retry failed:', retryRes.status, retryRes.statusText);
|
|
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);
|
|
113
142
|
}
|
|
114
143
|
else {
|
|
115
|
-
|
|
116
|
-
console.log('[ecom-package] Bridge auth retry response:', retryData);
|
|
117
|
-
if (retryData.cart_context) {
|
|
118
|
-
// Successfully obtained cart-context after retry
|
|
119
|
-
authData = retryData;
|
|
120
|
-
console.log('[ecom-package] cart-context obtained after retry:', authData.cart_context);
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
console.warn('[ecom-package] cart-context still missing after retry. Proceeding without it.');
|
|
124
|
-
}
|
|
144
|
+
console.warn('[ecom-package] No getCartFunction fallback. Proceeding without cart context.');
|
|
125
145
|
}
|
|
126
146
|
}
|
|
127
|
-
|
|
128
|
-
//
|
|
129
|
-
console.
|
|
130
|
-
|
|
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);
|
|
131
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');
|
|
132
168
|
}
|
|
133
|
-
|
|
134
|
-
console.warn('[ecom-package]
|
|
135
|
-
console.warn('[ecom-package] Tip: Pass getCartFunction prop to enable automatic cart creation when cookie is missing.');
|
|
169
|
+
catch (cookieErr) {
|
|
170
|
+
console.warn('[ecom-package] Failed to persist cart context cookie:', cookieErr);
|
|
136
171
|
}
|
|
137
172
|
}
|
|
138
173
|
// 2. Wait for BridgeChat to be available (with timeout)
|
|
@@ -209,6 +244,7 @@ position = 'bottom-right', backgroundColor = '#6366f1', foregroundColor = '#ffff
|
|
|
209
244
|
autoPopup,
|
|
210
245
|
onAuthSuccess,
|
|
211
246
|
onAuthError,
|
|
247
|
+
cartCreationMode,
|
|
212
248
|
getCartFunction
|
|
213
249
|
]);
|
|
214
250
|
(0, react_1.useEffect)(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatComponent.js","sourceRoot":"","sources":["../../src/ChatComponent.tsx"],"names":[],"mappings":"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
|
|
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,14 +43,28 @@ 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';
|
|
46
57
|
/**
|
|
47
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
|
+
*
|
|
48
62
|
* When cart-context cookie is missing, this function will be called
|
|
49
63
|
* to trigger cart creation (which sets the cookie), then bridge-auth
|
|
50
64
|
* is re-fetched to pick up the newly created cookie.
|
|
51
65
|
*
|
|
52
66
|
* Example: import { get as getCart } from 'services/cartService.client';
|
|
53
|
-
* <ChatComponent getCartFunction={getCart} />
|
|
67
|
+
* <ChatComponent getCartFunction={getCart} cartCreationMode="client" />
|
|
54
68
|
*/
|
|
55
69
|
getCartFunction?: () => Promise<any>;
|
|
56
70
|
}
|
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;IAErB
|
|
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, getCartFunction }) => {
|
|
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,42 +126,45 @@ 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);
|
|
97
|
-
// 2.
|
|
98
|
-
if (authData.cart_context_missing
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
});
|
|
108
|
-
if (!retryRes.ok) {
|
|
109
|
-
console.warn('[ecom-package] Bridge auth retry failed:', retryRes.status, retryRes.statusText);
|
|
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);
|
|
110
139
|
}
|
|
111
140
|
else {
|
|
112
|
-
|
|
113
|
-
console.log('[ecom-package] Bridge auth retry response:', retryData);
|
|
114
|
-
if (retryData.cart_context) {
|
|
115
|
-
// Successfully obtained cart-context after retry
|
|
116
|
-
authData = retryData;
|
|
117
|
-
console.log('[ecom-package] cart-context obtained after retry:', authData.cart_context);
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
console.warn('[ecom-package] cart-context still missing after retry. Proceeding without it.');
|
|
121
|
-
}
|
|
141
|
+
console.warn('[ecom-package] No getCartFunction fallback. Proceeding without cart context.');
|
|
122
142
|
}
|
|
123
143
|
}
|
|
124
|
-
|
|
125
|
-
//
|
|
126
|
-
console.
|
|
127
|
-
|
|
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);
|
|
128
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');
|
|
129
165
|
}
|
|
130
|
-
|
|
131
|
-
console.warn('[ecom-package]
|
|
132
|
-
console.warn('[ecom-package] Tip: Pass getCartFunction prop to enable automatic cart creation when cookie is missing.');
|
|
166
|
+
catch (cookieErr) {
|
|
167
|
+
console.warn('[ecom-package] Failed to persist cart context cookie:', cookieErr);
|
|
133
168
|
}
|
|
134
169
|
}
|
|
135
170
|
// 2. Wait for BridgeChat to be available (with timeout)
|
|
@@ -206,6 +241,7 @@ position = 'bottom-right', backgroundColor = '#6366f1', foregroundColor = '#ffff
|
|
|
206
241
|
autoPopup,
|
|
207
242
|
onAuthSuccess,
|
|
208
243
|
onAuthError,
|
|
244
|
+
cartCreationMode,
|
|
209
245
|
getCartFunction
|
|
210
246
|
]);
|
|
211
247
|
useEffect(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatComponent.js","sourceRoot":"","sources":["../../src/ChatComponent.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ChatComponent.js","sourceRoot":"","sources":["../../src/ChatComponent.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { ChatComponent } from '@bridge-ai-dev/ecom-chat';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ChatWrapper Component
|
|
7
|
+
*
|
|
8
|
+
* This component wraps the Bridge ChatComponent. By default, it uses
|
|
9
|
+
* 'server' cart creation mode, which relies on the /api/bridge-auth route
|
|
10
|
+
* to initialize the Litium cart context.
|
|
11
|
+
*/
|
|
12
|
+
export default function ChatWrapper() {
|
|
13
|
+
return (
|
|
14
|
+
<ChatComponent
|
|
15
|
+
tenantId={process.env.NEXT_PUBLIC_BRIDGE_TENANT_ID || ""}
|
|
16
|
+
widgetScriptUrl={process.env.NEXT_PUBLIC_BRIDGE_WIDGET_URL}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -1,49 +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.
|
|
11
|
-
*
|
|
12
|
-
* If the cart-context cookie is missing,
|
|
13
|
-
*
|
|
14
|
-
* and
|
|
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.
|
|
15
72
|
*/
|
|
16
73
|
export const GET = async (request: NextRequest) => {
|
|
17
74
|
const cookies = request.cookies;
|
|
18
75
|
|
|
19
|
-
// Debug: Log all available cookie names
|
|
20
|
-
const allCookieNames = cookies.getAll().map(c => c.name);
|
|
21
|
-
console.log('[bridge-auth] All cookie names:', allCookieNames);
|
|
22
76
|
console.log('[bridge-auth] Raw cookie header:', request.headers.get("cookie"));
|
|
23
|
-
|
|
77
|
+
|
|
24
78
|
// Retrieve the secure cookies
|
|
25
79
|
const identity = cookies.get(".AspNetCore.Identity.Application")?.value;
|
|
26
|
-
|
|
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'})` : '');
|
|
87
|
+
|
|
88
|
+
const responseCookies: Array<{ name: string; value: string; [k: string]: any }> = [];
|
|
89
|
+
|
|
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));
|
|
27
129
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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));
|
|
31
134
|
|
|
32
|
-
|
|
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[] ?? []);
|
|
33
141
|
|
|
34
|
-
|
|
35
|
-
|
|
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
|
+
}
|
|
36
183
|
}
|
|
37
184
|
|
|
38
|
-
const
|
|
185
|
+
const jsonBody = {
|
|
39
186
|
identity: identity || null,
|
|
40
187
|
cart_context: cartContext || null,
|
|
41
|
-
cart_context_missing:
|
|
42
|
-
|
|
43
|
-
raw: request.headers.get("cookie")
|
|
188
|
+
cart_context_missing: !cartContext,
|
|
189
|
+
raw: request.headers.get("cookie"),
|
|
44
190
|
};
|
|
45
191
|
|
|
46
|
-
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
|
+
}
|
|
47
206
|
|
|
48
|
-
return
|
|
207
|
+
return response;
|
|
49
208
|
};
|