@remkoj/optimizely-one-nextjs 1.0.3
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/LICENSE +13 -0
- package/README.md +82 -0
- package/dist/api/graph-info-service.d.ts +14 -0
- package/dist/api/graph-info-service.js +37 -0
- package/dist/api/graph-info-service.js.map +1 -0
- package/dist/api/index.d.ts +20 -0
- package/dist/api/index.js +42 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/profile-api-service.d.ts +21 -0
- package/dist/api/profile-api-service.js +80 -0
- package/dist/api/profile-api-service.js.map +1 -0
- package/dist/api/responses.d.ts +2 -0
- package/dist/api/responses.js +2 -0
- package/dist/api/responses.js.map +1 -0
- package/dist/api/types.d.ts +18 -0
- package/dist/api/types.js +2 -0
- package/dist/api/types.js.map +1 -0
- package/dist/api.d.ts +5 -0
- package/dist/api.js +4 -0
- package/dist/api.js.map +1 -0
- package/dist/client-types.d.ts +133 -0
- package/dist/client-types.js +2 -0
- package/dist/client-types.js.map +1 -0
- package/dist/client.d.ts +3 -0
- package/dist/client.js +3 -0
- package/dist/client.js.map +1 -0
- package/dist/components/context.d.ts +88 -0
- package/dist/components/context.js +71 -0
- package/dist/components/context.js.map +1 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.js +5 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/optimizely-one-gadget/audiences-panel.d.ts +7 -0
- package/dist/components/optimizely-one-gadget/audiences-panel.js +53 -0
- package/dist/components/optimizely-one-gadget/audiences-panel.js.map +1 -0
- package/dist/components/optimizely-one-gadget/exp-panel.d.ts +3 -0
- package/dist/components/optimizely-one-gadget/exp-panel.js +42 -0
- package/dist/components/optimizely-one-gadget/exp-panel.js.map +1 -0
- package/dist/components/optimizely-one-gadget/graph-panel.d.ts +7 -0
- package/dist/components/optimizely-one-gadget/graph-panel.js +27 -0
- package/dist/components/optimizely-one-gadget/graph-panel.js.map +1 -0
- package/dist/components/optimizely-one-gadget/ids-panel.d.ts +7 -0
- package/dist/components/optimizely-one-gadget/ids-panel.js +23 -0
- package/dist/components/optimizely-one-gadget/ids-panel.js.map +1 -0
- package/dist/components/optimizely-one-gadget/index.d.ts +33 -0
- package/dist/components/optimizely-one-gadget/index.js +39 -0
- package/dist/components/optimizely-one-gadget/index.js.map +1 -0
- package/dist/components/optimizely-one-gadget/interests-panel.d.ts +7 -0
- package/dist/components/optimizely-one-gadget/interests-panel.js +23 -0
- package/dist/components/optimizely-one-gadget/interests-panel.js.map +1 -0
- package/dist/components/optimizely-one-gadget/logo.d.ts +6 -0
- package/dist/components/optimizely-one-gadget/logo.js +19 -0
- package/dist/components/optimizely-one-gadget/logo.js.map +1 -0
- package/dist/components/page-activator.d.ts +4 -0
- package/dist/components/page-activator.js +32 -0
- package/dist/components/page-activator.js.map +1 -0
- package/dist/components/use-test-mode.d.ts +11 -0
- package/dist/components/use-test-mode.js +81 -0
- package/dist/components/use-test-mode.js.map +1 -0
- package/dist/env-vars.d.ts +13 -0
- package/dist/env-vars.js +15 -0
- package/dist/env-vars.js.map +1 -0
- package/dist/products/client-types.d.ts +3 -0
- package/dist/products/client-types.js +2 -0
- package/dist/products/client-types.js.map +1 -0
- package/dist/products/content-recs/api.d.ts +19 -0
- package/dist/products/content-recs/api.js +42 -0
- package/dist/products/content-recs/api.js.map +1 -0
- package/dist/products/content-recs/client.d.ts +10 -0
- package/dist/products/content-recs/client.js +29 -0
- package/dist/products/content-recs/client.js.map +1 -0
- package/dist/products/content-recs/helpers.d.ts +20 -0
- package/dist/products/content-recs/helpers.js +27 -0
- package/dist/products/content-recs/helpers.js.map +1 -0
- package/dist/products/content-recs/index.d.ts +2 -0
- package/dist/products/content-recs/index.js +3 -0
- package/dist/products/content-recs/index.js.map +1 -0
- package/dist/products/data-platform/api.d.ts +41 -0
- package/dist/products/data-platform/api.js +116 -0
- package/dist/products/data-platform/api.js.map +1 -0
- package/dist/products/data-platform/client.d.ts +14 -0
- package/dist/products/data-platform/client.js +59 -0
- package/dist/products/data-platform/client.js.map +1 -0
- package/dist/products/data-platform/helpers.d.ts +22 -0
- package/dist/products/data-platform/helpers.js +31 -0
- package/dist/products/data-platform/helpers.js.map +1 -0
- package/dist/products/data-platform/index.d.ts +10 -0
- package/dist/products/data-platform/index.js +10 -0
- package/dist/products/data-platform/index.js.map +1 -0
- package/dist/products/index.d.ts +3 -0
- package/dist/products/index.js +4 -0
- package/dist/products/index.js.map +1 -0
- package/dist/products/types.d.ts +2 -0
- package/dist/products/types.js +2 -0
- package/dist/products/types.js.map +1 -0
- package/dist/products/web-experimentation/client.d.ts +11 -0
- package/dist/products/web-experimentation/client.js +42 -0
- package/dist/products/web-experimentation/client.js.map +1 -0
- package/dist/products/web-experimentation/helpers.d.ts +13 -0
- package/dist/products/web-experimentation/helpers.js +14 -0
- package/dist/products/web-experimentation/helpers.js.map +1 -0
- package/dist/products/web-experimentation/index.d.ts +1 -0
- package/dist/products/web-experimentation/index.js +2 -0
- package/dist/products/web-experimentation/index.js.map +1 -0
- package/dist/server-components/index.d.ts +1 -0
- package/dist/server-components/index.js +2 -0
- package/dist/server-components/index.js.map +1 -0
- package/dist/server-components/scripts/footer.d.ts +6 -0
- package/dist/server-components/scripts/footer.js +11 -0
- package/dist/server-components/scripts/footer.js.map +1 -0
- package/dist/server-components/scripts/header.d.ts +6 -0
- package/dist/server-components/scripts/header.js +12 -0
- package/dist/server-components/scripts/header.js.map +1 -0
- package/dist/server-components/scripts/index.d.ts +18 -0
- package/dist/server-components/scripts/index.js +19 -0
- package/dist/server-components/scripts/index.js.map +1 -0
- package/dist/server-components/scripts/snippets/optimizely-content-recs.d.ts +6 -0
- package/dist/server-components/scripts/snippets/optimizely-content-recs.js +19 -0
- package/dist/server-components/scripts/snippets/optimizely-content-recs.js.map +1 -0
- package/dist/server-components/scripts/snippets/optimizely-data-patform.d.ts +5 -0
- package/dist/server-components/scripts/snippets/optimizely-data-patform.js +37 -0
- package/dist/server-components/scripts/snippets/optimizely-data-patform.js.map +1 -0
- package/dist/server-components/scripts/snippets/optimizely-web-experimentation.d.ts +5 -0
- package/dist/server-components/scripts/snippets/optimizely-web-experimentation.js +9 -0
- package/dist/server-components/scripts/snippets/optimizely-web-experimentation.js.map +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.js +11 -0
- package/dist/server.js.map +1 -0
- package/dist/styles.css +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/env.d.ts +11 -0
- package/dist/utils/env.js +49 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/session.d.ts +11 -0
- package/dist/utils/session.js +28 -0
- package/dist/utils/session.js.map +1 -0
- package/package.json +78 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2024 Remko Jantzen
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Next.JS Optimizely One toolkit
|
|
2
|
+
React components (both client & server) to integrate the browser-side products from Optimizely (Web Experimentation, Data Platform & Content Analytics / Recommendations)
|
|
3
|
+
|
|
4
|
+
## Requirements
|
|
5
|
+
- Next.JS 14.1+
|
|
6
|
+
- TypeScript
|
|
7
|
+
- Access to the Optimizely One Products
|
|
8
|
+
|
|
9
|
+
## Installing & Usage
|
|
10
|
+
|
|
11
|
+
Start by adding the package to your project:
|
|
12
|
+
`yarn add @remkoj/optimizely-one-nextjs`
|
|
13
|
+
|
|
14
|
+
### Add API Routes
|
|
15
|
+
Then make the service endpoints available by creating a new API route within Next.JS. For the app router this is done by creating this file:
|
|
16
|
+
|
|
17
|
+
`app/api/me/[[...path]]/route.ts`
|
|
18
|
+
|
|
19
|
+
Put the following code in this file to use the API Route handler from the package:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { createOptimizelyOneApi } from '@remkoj/optimizely-one-nextjs/server';
|
|
23
|
+
|
|
24
|
+
const handler = createOptimizelyOneApi()
|
|
25
|
+
|
|
26
|
+
export const GET = handler
|
|
27
|
+
export const POST = handler
|
|
28
|
+
export const runtime = 'edge' // 'nodejs' (default) | 'edge'
|
|
29
|
+
export const dynamic = 'force-dynamic'
|
|
30
|
+
export const dynamicParams = true
|
|
31
|
+
export const fetchCache = 'default-no-store'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Add Provider & PageTracker to your layout
|
|
35
|
+
Within the global layout (or your ["third party providers component"](https://vercel.com/guides/react-context-state-management-nextjs#rendering-third-party-context-providers-in-server-components), whatever applies best), add the Optimizely One Scripts (`Scripts.Header` & `Scripts.Footer`), Context Provider (`OptimizelyOneProvider`), Page Activator (`PageActivator`), and - if you want to - the demo gadget (`OptimizelyOneGadget`).
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { Scripts } from '@remkoj/optimizely-one-nextjs/server'
|
|
39
|
+
import { OptimizelyOneProvider, PageActivator } from '@remkoj/optimizely-one-nextjs/client'
|
|
40
|
+
import OptimizelyOneGadget from '@remkoj/optimizely-one-nextjs/optimizely-one-gadget'
|
|
41
|
+
|
|
42
|
+
export type RootLayoutProps = {
|
|
43
|
+
children: React.ReactNode
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default function RootLayout({ children }: RootLayoutProps)
|
|
47
|
+
{
|
|
48
|
+
return <html>
|
|
49
|
+
<head>
|
|
50
|
+
<Scripts.Header />
|
|
51
|
+
</head>
|
|
52
|
+
<body>
|
|
53
|
+
<OptimizelyOneProvider value={{ debug: true }}>
|
|
54
|
+
<PageActivator />
|
|
55
|
+
{ children }
|
|
56
|
+
<OptimizelyOneGadget />
|
|
57
|
+
</OptimizelyOneProvider>
|
|
58
|
+
<Scripts.Footer />
|
|
59
|
+
</body>
|
|
60
|
+
</html>
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Instrument your site with additional events
|
|
65
|
+
Whenever you want to track additional events, use the provided hook to get to the context and send events.
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
'use client'
|
|
69
|
+
import React, { type FunctionComponent } from 'react'
|
|
70
|
+
import { useOptimizelyOne } from '@remkoj/optimizely-one-nextjs/client'
|
|
71
|
+
|
|
72
|
+
export const YourComponent : FunctionComponent<{}> = props => {
|
|
73
|
+
const opti = useOptimizelyOne()
|
|
74
|
+
|
|
75
|
+
function handler()
|
|
76
|
+
{
|
|
77
|
+
opti?.track({ event: "name", action: "action" })
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return <button onClick={() => handler()}>Output</button>
|
|
81
|
+
}
|
|
82
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ApiService } from './types';
|
|
2
|
+
export declare const GraphInfoApiService: ApiService<GraphInfoApiResponse>;
|
|
3
|
+
export default GraphInfoApiService;
|
|
4
|
+
export type GraphInfoApiResponse = {
|
|
5
|
+
hooks: {
|
|
6
|
+
url: string;
|
|
7
|
+
hasQueryParams?: boolean;
|
|
8
|
+
method?: string;
|
|
9
|
+
}[];
|
|
10
|
+
sources: {
|
|
11
|
+
label: string;
|
|
12
|
+
languages: string[];
|
|
13
|
+
}[];
|
|
14
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as EnvTools from '../utils/env';
|
|
2
|
+
import EnvVars from '../env-vars';
|
|
3
|
+
import * as Responses from './responses';
|
|
4
|
+
import createAdminApi from '@remkoj/optimizely-graph-client/admin';
|
|
5
|
+
export const GraphInfoApiService = {
|
|
6
|
+
for: { path: '/graph', verb: 'get' },
|
|
7
|
+
handler: async (query, cookies) => {
|
|
8
|
+
// Check if the toolkit is enabled
|
|
9
|
+
if (!EnvTools.readValueAsBoolean(EnvVars.HelperEnabled, false))
|
|
10
|
+
return Responses.NotFound;
|
|
11
|
+
const adminApi = createAdminApi();
|
|
12
|
+
const hooks = await adminApi.webhooks.listWebhookHandler();
|
|
13
|
+
const sourceMap = await adminApi.definitionV3.getContentV3SourceHandler();
|
|
14
|
+
const sources = [];
|
|
15
|
+
for (const sourceId in sourceMap) {
|
|
16
|
+
const source = sourceMap[sourceId];
|
|
17
|
+
sources.push({
|
|
18
|
+
label: source.label,
|
|
19
|
+
languages: source.languages
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return [{
|
|
23
|
+
hooks: hooks.map(hook => {
|
|
24
|
+
const hookUrl = new URL(hook.request.url);
|
|
25
|
+
const visibleUrl = hookUrl.protocol + '//' + hookUrl.host + hookUrl.pathname;
|
|
26
|
+
return {
|
|
27
|
+
url: visibleUrl,
|
|
28
|
+
hasQueryParams: hook.request.url != visibleUrl,
|
|
29
|
+
method: hook.request.method
|
|
30
|
+
};
|
|
31
|
+
}),
|
|
32
|
+
sources
|
|
33
|
+
}, 200];
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
export default GraphInfoApiService;
|
|
37
|
+
//# sourceMappingURL=graph-info-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-info-service.js","sourceRoot":"","sources":["../../src/api/graph-info-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,cAAc,CAAA;AACxC,OAAO,OAAO,MAAM,aAAa,CAAA;AACjC,OAAO,KAAK,SAAS,MAAM,aAAa,CAAA;AACxC,OAAO,cAAc,MAAM,uCAAuC,CAAA;AAGlE,MAAM,CAAC,MAAM,mBAAmB,GAAsC;IAClE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE;IACpC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC9B,kCAAkC;QAClC,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC;YAC1D,OAAO,SAAS,CAAC,QAAQ,CAAA;QAE7B,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAA;QAEjC,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAA;QAC1D,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,yBAAyB,EAAE,CAAA;QACzE,MAAM,OAAO,GAAW,EAAE,CAAA;QAC1B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;YAClC,OAAO,CAAC,IAAI,CAAC;gBACT,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,SAAS,EAAE,MAAM,CAAC,SAAS;aAC9B,CAAC,CAAA;QACN,CAAC;QAED,OAAO,CAAC;gBACJ,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;oBACpB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;oBACzC,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAA;oBAC5E,OAAO;wBACH,GAAG,EAAE,UAAU;wBACf,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,UAAU;wBAC9C,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;qBAC9B,CAAA;gBACL,CAAC,CAAC;gBACF,OAAO;aACV,EAAE,GAAG,CAAC,CAAA;IACX,CAAC;CACJ,CAAA;AAED,eAAe,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import 'server-only';
|
|
2
|
+
import { type NextRequest, NextResponse } from 'next/server';
|
|
3
|
+
import type { ApiService } from './types';
|
|
4
|
+
type RequestContext = {
|
|
5
|
+
params: Record<string, string | string[]>;
|
|
6
|
+
};
|
|
7
|
+
type OptimizelyOneApi = (req: NextRequest, ctx: RequestContext) => Promise<NextResponse>;
|
|
8
|
+
export type OptimizelyOneApiConfig = {
|
|
9
|
+
/**
|
|
10
|
+
* The URL Parameter you've setup in your Next.JS router to catch the
|
|
11
|
+
* full path to be handled.
|
|
12
|
+
*/
|
|
13
|
+
pathParameterName: string;
|
|
14
|
+
/**
|
|
15
|
+
* Inject any project specific services into the OptimizelyOne API
|
|
16
|
+
*/
|
|
17
|
+
services: ApiService[];
|
|
18
|
+
};
|
|
19
|
+
export declare function createOptimizelyOneApi(config?: Partial<OptimizelyOneApiConfig>): OptimizelyOneApi;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import 'server-only';
|
|
2
|
+
import { NextResponse } from 'next/server';
|
|
3
|
+
import { cookies } from 'next/headers';
|
|
4
|
+
import ProfileApiService from './profile-api-service';
|
|
5
|
+
import GraphInfoApiService from './graph-info-service';
|
|
6
|
+
export function createOptimizelyOneApi(config) {
|
|
7
|
+
const pathParameterName = config?.pathParameterName ?? 'path';
|
|
8
|
+
const services = [
|
|
9
|
+
...(config?.services || []),
|
|
10
|
+
ProfileApiService,
|
|
11
|
+
GraphInfoApiService
|
|
12
|
+
];
|
|
13
|
+
// Basic service matcher, but get's the job done for now
|
|
14
|
+
function matchService(verb, path, serviceFor) {
|
|
15
|
+
return serviceFor.path.toLowerCase() == path.toLowerCase() &&
|
|
16
|
+
serviceFor.verb.toLowerCase() == verb.toLowerCase();
|
|
17
|
+
}
|
|
18
|
+
async function handler(request, context) {
|
|
19
|
+
// Determine the current path & basePath for handling the request
|
|
20
|
+
let apiPath = context.params[pathParameterName];
|
|
21
|
+
if (!apiPath)
|
|
22
|
+
apiPath = '/';
|
|
23
|
+
else if (Array.isArray(apiPath))
|
|
24
|
+
apiPath = '/' + apiPath.join('/');
|
|
25
|
+
else if (!apiPath.startsWith('/'))
|
|
26
|
+
apiPath = '/' + apiPath;
|
|
27
|
+
const path = apiPath;
|
|
28
|
+
//const basePath = apiPath == '/' ? request.nextUrl.pathname : request.nextUrl.pathname.endsWith(apiPath) ? request.nextUrl.pathname.substring(0, request.nextUrl.pathname.lastIndexOf(apiPath)) : ''
|
|
29
|
+
const verb = request.method;
|
|
30
|
+
// Find the service
|
|
31
|
+
const apiService = services.find(service => matchService(verb, path, service.for));
|
|
32
|
+
if (!apiService)
|
|
33
|
+
return NextResponse.json({ error: { status: 404, message: "Not found" } }, { status: 404 });
|
|
34
|
+
// Invoke the service
|
|
35
|
+
const c = cookies();
|
|
36
|
+
const [response, statusCode] = await apiService.handler(request.nextUrl.searchParams, c);
|
|
37
|
+
// Return the outcome
|
|
38
|
+
return NextResponse.json(response, { status: statusCode });
|
|
39
|
+
}
|
|
40
|
+
return handler;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AACpB,OAAO,EAAoB,YAAY,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,OAAO,iBAAiB,MAAM,uBAAuB,CAAA;AACrD,OAAO,mBAAmB,MAAM,sBAAsB,CAAA;AAkBtD,MAAM,UAAU,sBAAsB,CAAC,MAAwC;IAE3E,MAAM,iBAAiB,GAAG,MAAM,EAAE,iBAAiB,IAAI,MAAM,CAAA;IAC7D,MAAM,QAAQ,GAAG;QACb,GAAG,CAAC,MAAM,EAAE,QAAQ,IAAI,EAAE,CAAC;QAC3B,iBAAiB;QACjB,mBAAmB;KACtB,CAAA;IAED,wDAAwD;IACxD,SAAS,YAAY,CAAC,IAAY,EAAE,IAAY,EAAE,UAA6B;QAE3E,OAAO,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,WAAW,EAAE;YACtD,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAA;IAC3D,CAAC;IAED,KAAK,UAAU,OAAO,CAAC,OAAoB,EAAE,OAAuB;QAEhE,iEAAiE;QACjE,IAAI,OAAO,GAAmC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAA;QAC/E,IAAI,CAAC,OAAO;YAAE,OAAO,GAAG,GAAG,CAAA;aACtB,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YAAE,OAAO,GAAG,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;aAC7D,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,GAAG,GAAG,OAAO,CAAA;QAC1D,MAAM,IAAI,GAAY,OAAO,CAAA;QAC7B,qMAAqM;QACrM,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAA;QAE3B,mBAAmB;QACnB,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAC,IAAI,EAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;QAChF,IAAI,CAAC,UAAU;YACX,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,EAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;QAE9F,qBAAqB;QACrB,MAAM,CAAC,GAAG,OAAO,EAAE,CAAA;QACnB,MAAM,CAAE,QAAQ,EAAE,UAAU,CAAE,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;QAE1F,qBAAqB;QACrB,OAAO,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAA;IAC9D,CAAC;IACD,OAAO,OAAO,CAAA;AAClB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ApiService } from './types';
|
|
2
|
+
export declare const ProfileApiService: ApiService<ProfileApiResponse>;
|
|
3
|
+
export default ProfileApiService;
|
|
4
|
+
export type ProfileApiResponse = {
|
|
5
|
+
ids: {
|
|
6
|
+
frontend: string;
|
|
7
|
+
dataPlatform: string;
|
|
8
|
+
contentIntelligence: string;
|
|
9
|
+
webExperimentation: string;
|
|
10
|
+
};
|
|
11
|
+
contentTopics: string[];
|
|
12
|
+
audiences: {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
}[];
|
|
16
|
+
audiencesPageCount: number;
|
|
17
|
+
audiencesCount: number;
|
|
18
|
+
pageSize: number;
|
|
19
|
+
pageNumber: number;
|
|
20
|
+
duration?: string;
|
|
21
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as EnvTools from '../utils/env';
|
|
2
|
+
import EnvVars from '../env-vars';
|
|
3
|
+
import * as Responses from './responses';
|
|
4
|
+
import Session from '../utils/session';
|
|
5
|
+
import { DataPlatform, ContentRecs, WebExperimentation } from '../products';
|
|
6
|
+
const NO_ID = 'n/a';
|
|
7
|
+
export const ProfileApiService = {
|
|
8
|
+
for: { path: '/', verb: 'get' },
|
|
9
|
+
handler: async (query, cookies) => {
|
|
10
|
+
// Check if the toolkit is enabled
|
|
11
|
+
if (!EnvTools.readValueAsBoolean(EnvVars.HelperEnabled, false))
|
|
12
|
+
return Responses.NotFound;
|
|
13
|
+
// Start timer
|
|
14
|
+
let start = Date.now();
|
|
15
|
+
// Read requested scopes
|
|
16
|
+
const scopes = query.get('scope')?.toLowerCase()?.split(',')?.map(x => x.trim());
|
|
17
|
+
const fetchContentTopics = !scopes || scopes.includes('topics');
|
|
18
|
+
const fetchODPAudiences = !scopes || scopes.includes('audiences');
|
|
19
|
+
// Read all IDs
|
|
20
|
+
const odpId = DataPlatform.Tools.getVisitorID(cookies);
|
|
21
|
+
const crId = ContentRecs.Tools.getVisitorID(cookies);
|
|
22
|
+
const webExId = WebExperimentation.Tools.getVisitorID(cookies);
|
|
23
|
+
const frontendId = Session.getVisitorId(cookies);
|
|
24
|
+
// Read parameters & set values
|
|
25
|
+
const pageSize = Math.max(stringToInt(query.get('limit'), 10), 1);
|
|
26
|
+
const pageNumber = Math.max(stringToInt(query.get('page'), 0), 0);
|
|
27
|
+
let audiencesPageCount = 0;
|
|
28
|
+
let audiencesCount = 0;
|
|
29
|
+
// Determine audiences if needed
|
|
30
|
+
let audiences = [];
|
|
31
|
+
if (fetchODPAudiences && odpId) {
|
|
32
|
+
const odp = new DataPlatform.Client();
|
|
33
|
+
const allAudiences = await odp.getAllAudiences();
|
|
34
|
+
audiencesCount = allAudiences.length;
|
|
35
|
+
// Split the list into manageable groups
|
|
36
|
+
const chunks = [];
|
|
37
|
+
allAudiences.forEach((item, idx) => {
|
|
38
|
+
const chunkId = Math.floor(idx / EnvTools.readValueAsInt(EnvVars.OdpAudienceBatchSize, pageSize));
|
|
39
|
+
chunks[chunkId] = chunks[chunkId] || [];
|
|
40
|
+
chunks[chunkId].push(item.id);
|
|
41
|
+
});
|
|
42
|
+
audiencesPageCount = chunks.length;
|
|
43
|
+
// Apply filtering to the audiences
|
|
44
|
+
const userAudienceIds = /*chunkNr == 0 ?
|
|
45
|
+
(await Promise.all(chunks.map(chunk => odp.filterAudiences(odpId, chunk)))).flat() :*/ await odp.filterAudiences(odpId, chunks[pageNumber]);
|
|
46
|
+
audiences = allAudiences.filter(a => userAudienceIds.includes(a.id));
|
|
47
|
+
}
|
|
48
|
+
// Determine topics if needed
|
|
49
|
+
let topics = [];
|
|
50
|
+
if (fetchContentTopics && crId) {
|
|
51
|
+
const contentRecs = new ContentRecs.Client();
|
|
52
|
+
topics = await contentRecs.getContentTopics(crId);
|
|
53
|
+
}
|
|
54
|
+
return [{
|
|
55
|
+
ids: {
|
|
56
|
+
dataPlatform: odpId || NO_ID,
|
|
57
|
+
frontend: frontendId || NO_ID,
|
|
58
|
+
contentIntelligence: crId || NO_ID,
|
|
59
|
+
webExperimentation: webExId || NO_ID
|
|
60
|
+
},
|
|
61
|
+
pageSize,
|
|
62
|
+
pageNumber,
|
|
63
|
+
audiences: audiences,
|
|
64
|
+
audiencesPageCount,
|
|
65
|
+
audiencesCount,
|
|
66
|
+
contentTopics: topics,
|
|
67
|
+
duration: `${Date.now() - start}ms`
|
|
68
|
+
}, 200];
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
export default ProfileApiService;
|
|
72
|
+
function stringToInt(value, defaultValue) {
|
|
73
|
+
try {
|
|
74
|
+
const result = Number.parseInt(value ?? defaultValue.toString(), 10);
|
|
75
|
+
return isNaN(result) ? defaultValue : result;
|
|
76
|
+
}
|
|
77
|
+
catch { }
|
|
78
|
+
return defaultValue;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=profile-api-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-api-service.js","sourceRoot":"","sources":["../../src/api/profile-api-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responses.js","sourceRoot":"","sources":["../../src/api/responses.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,QAAQ,GAA6B,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,EAAC,EAAE,GAAG,CAAC,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { cookies } from 'next/headers';
|
|
2
|
+
type ReadonlyRequestCookies = ReturnType<typeof cookies>;
|
|
3
|
+
export type ApiServiceErrorMessage = {
|
|
4
|
+
error: {
|
|
5
|
+
status: number;
|
|
6
|
+
message: string;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export type ApiServiceErrorResponse = [ApiServiceErrorMessage, number];
|
|
10
|
+
export type ApiServiceResponse<T extends {} = {}> = [T, 200 | undefined] | ApiServiceErrorResponse;
|
|
11
|
+
export type ApiService<T extends {} = {}> = {
|
|
12
|
+
for: {
|
|
13
|
+
path: string;
|
|
14
|
+
verb: string;
|
|
15
|
+
};
|
|
16
|
+
handler: (query: URLSearchParams, cookies: ReadonlyRequestCookies) => Promise<ApiServiceResponse<T>>;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":""}
|
package/dist/api.d.ts
ADDED
package/dist/api.js
ADDED
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACpD,cAAc,YAAY,CAAA;AAC1B,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface Window {
|
|
3
|
+
zaius?: OptimizelyDataPlatformApi;
|
|
4
|
+
_iaq?: OptimizelyContentRecsApi;
|
|
5
|
+
optimizely?: OptimizelyWebExperimentationApi;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export interface OptimizelyOneService<T = any> {
|
|
9
|
+
order: Readonly<number>;
|
|
10
|
+
isActive: Readonly<boolean>;
|
|
11
|
+
code: Readonly<string>;
|
|
12
|
+
debug: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Perform any actions that must be done to apply the capabilities of this
|
|
15
|
+
* service on the page. This function MUST NOT perform behaviour tracking of
|
|
16
|
+
* any kind.
|
|
17
|
+
*
|
|
18
|
+
* @param path The path for which to activate.
|
|
19
|
+
* @returns void
|
|
20
|
+
*/
|
|
21
|
+
activatePage?: (path: string) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Perform any actions that must be done to performt the pageview tracking
|
|
24
|
+
* needed for this service.
|
|
25
|
+
*
|
|
26
|
+
* @param path The path for which to activate.
|
|
27
|
+
* @returns void
|
|
28
|
+
*/
|
|
29
|
+
trackPage?: (path: string) => void;
|
|
30
|
+
trackEvent?: (event: OptimizelyOneEvent) => void;
|
|
31
|
+
updateProfile?: (profileData: OptimizelyOneProfileData) => void;
|
|
32
|
+
getBrowserApi: () => T | undefined;
|
|
33
|
+
}
|
|
34
|
+
export type OptimizelyOneEvent = NavigationSearchEvent | {
|
|
35
|
+
event: string;
|
|
36
|
+
action: string;
|
|
37
|
+
[key: string]: string | number | boolean;
|
|
38
|
+
};
|
|
39
|
+
type NavigationSearchEvent = {
|
|
40
|
+
event: "navigation";
|
|
41
|
+
action: "search";
|
|
42
|
+
search_term: string;
|
|
43
|
+
};
|
|
44
|
+
export type OptimizelyOneProfileData = {
|
|
45
|
+
content_intelligence_id: string;
|
|
46
|
+
custom: Record<string, string | number | boolean>;
|
|
47
|
+
};
|
|
48
|
+
export type OptimizelyDataPlatformApi = {
|
|
49
|
+
event: (name: string, data?: {
|
|
50
|
+
[param: string]: any;
|
|
51
|
+
}) => Promise<void>;
|
|
52
|
+
dispatch: (group: string, action: string, params?: {
|
|
53
|
+
[param: string]: any;
|
|
54
|
+
}) => Promise<void>;
|
|
55
|
+
customer: (customerProps: any) => void;
|
|
56
|
+
};
|
|
57
|
+
export type OptimizelyContentRecsApi = {
|
|
58
|
+
push: (command: [string, any]) => void;
|
|
59
|
+
};
|
|
60
|
+
export type OptimizelyWebExperimentationApi = {
|
|
61
|
+
initialized: boolean;
|
|
62
|
+
push: (data: {
|
|
63
|
+
type: string;
|
|
64
|
+
[paramName: string]: any;
|
|
65
|
+
}) => void;
|
|
66
|
+
get?: <T extends keyof OptlyWebGet>(what: T) => OptlyWebGet[T];
|
|
67
|
+
};
|
|
68
|
+
export type OptlyWebGet = {
|
|
69
|
+
state: {
|
|
70
|
+
getPageStates: (filters?: {
|
|
71
|
+
isActive: boolean;
|
|
72
|
+
}) => {
|
|
73
|
+
[id: string]: {
|
|
74
|
+
id: string;
|
|
75
|
+
apiName: string;
|
|
76
|
+
name: string | null;
|
|
77
|
+
isActive: boolean;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
getExperimentStates: (filters?: {
|
|
81
|
+
isActive: boolean;
|
|
82
|
+
}) => {
|
|
83
|
+
[id: string]: {
|
|
84
|
+
audiences: any[];
|
|
85
|
+
experimentName: string | null;
|
|
86
|
+
id: string;
|
|
87
|
+
isActive: boolean;
|
|
88
|
+
isInExperimentHoldback: boolean;
|
|
89
|
+
reason?: undefined | string;
|
|
90
|
+
variation: {
|
|
91
|
+
id: string;
|
|
92
|
+
name: string | null;
|
|
93
|
+
};
|
|
94
|
+
visitorRedirected: boolean;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
getCampaignStates: (filters?: {
|
|
98
|
+
isActive: boolean;
|
|
99
|
+
}) => {
|
|
100
|
+
[id: string]: {
|
|
101
|
+
allExperiments: {
|
|
102
|
+
id: string;
|
|
103
|
+
name: string;
|
|
104
|
+
}[];
|
|
105
|
+
audiences: {
|
|
106
|
+
id: string;
|
|
107
|
+
name: string;
|
|
108
|
+
}[];
|
|
109
|
+
campaignName: string;
|
|
110
|
+
experiment: {
|
|
111
|
+
campaignName: string;
|
|
112
|
+
id: string;
|
|
113
|
+
name: string;
|
|
114
|
+
};
|
|
115
|
+
id: string;
|
|
116
|
+
isActive: boolean;
|
|
117
|
+
isInCampaignHoldback: boolean;
|
|
118
|
+
reason?: any;
|
|
119
|
+
variation: {
|
|
120
|
+
id: string;
|
|
121
|
+
name: string;
|
|
122
|
+
};
|
|
123
|
+
visitorRedirected: boolean;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
data: {
|
|
128
|
+
projectId: string;
|
|
129
|
+
accountId: string;
|
|
130
|
+
revision: string;
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-types.js","sourceRoot":"","sources":["../src/client-types.ts"],"names":[],"mappings":""}
|
package/dist/client.d.ts
ADDED
package/dist/client.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA,CAAC,gDAAgD;AAC3E,cAAc,cAAc,CAAA,CAAC,yBAAyB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type FunctionComponent, type PropsWithChildren } from 'react';
|
|
2
|
+
import WebExperimenationService from '../products/web-experimentation/client';
|
|
3
|
+
import DataPlatformService from '../products/data-platform/client';
|
|
4
|
+
import ContentRecsService from '../products/content-recs/client';
|
|
5
|
+
import * as ClientApi from '../client-types';
|
|
6
|
+
/**
|
|
7
|
+
* The data stored within the OptimizelyOne context
|
|
8
|
+
*/
|
|
9
|
+
type OptimizelyOneContextType = {
|
|
10
|
+
/**
|
|
11
|
+
* With tracking completely disabled, all events will be stopped by
|
|
12
|
+
* the OptimizelyOne hook. The "PageActivator" component will propagate
|
|
13
|
+
* this instruction to all configured Optimizely One services
|
|
14
|
+
*/
|
|
15
|
+
disableTracking?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* With auto-tracking disabled, the "PageActivator" component will not
|
|
18
|
+
* automatically track a generic pageview for all configured Optimizely
|
|
19
|
+
* One services.
|
|
20
|
+
*/
|
|
21
|
+
disableAutotracking?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* The list of services Optimizely One Services registered with the
|
|
24
|
+
* context. When creating the context, you may only add to the existing
|
|
25
|
+
* service.
|
|
26
|
+
*/
|
|
27
|
+
services?: Readonly<ClientApi.OptimizelyOneService[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Whether or not debug output ging must be enabled
|
|
30
|
+
*/
|
|
31
|
+
debug?: boolean;
|
|
32
|
+
setDebug: (newDebug: boolean) => void;
|
|
33
|
+
addService: (service: ClientApi.OptimizelyOneService) => void;
|
|
34
|
+
removeService: (service: ClientApi.OptimizelyOneService) => void;
|
|
35
|
+
};
|
|
36
|
+
type OptimizelyOneProviderProps = PropsWithChildren<{
|
|
37
|
+
value?: Omit<OptimizelyOneContextType, 'setDebug' | 'addService' | 'removeService'>;
|
|
38
|
+
}>;
|
|
39
|
+
type OptimizelyOneServiceMap = Record<string, ClientApi.OptimizelyOneService>;
|
|
40
|
+
interface DefaultServiceMap extends OptimizelyOneServiceMap {
|
|
41
|
+
webex: InstanceType<typeof WebExperimenationService>;
|
|
42
|
+
odp: InstanceType<typeof DataPlatformService>;
|
|
43
|
+
crecs: InstanceType<typeof ContentRecsService>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The results of the invokation of the useOptimizelyOne
|
|
47
|
+
* hook
|
|
48
|
+
*/
|
|
49
|
+
type OptimizelyOneHookResult<TM extends DefaultServiceMap = DefaultServiceMap> = OptimizelyOneContextType & {
|
|
50
|
+
/**
|
|
51
|
+
* Track an event using the generic events api, which allows all configured
|
|
52
|
+
* Optimizely One services to receive this event
|
|
53
|
+
*
|
|
54
|
+
* @param event The event data to send
|
|
55
|
+
* @returns
|
|
56
|
+
*/
|
|
57
|
+
track: (event: ClientApi.OptimizelyOneEvent) => void;
|
|
58
|
+
/**
|
|
59
|
+
* Retrieve all services that must be invoked on the "activate page" step of
|
|
60
|
+
* the execution cycle
|
|
61
|
+
*
|
|
62
|
+
* @returns A list of active services
|
|
63
|
+
*/
|
|
64
|
+
getActivatePageServices: () => (Omit<ClientApi.OptimizelyOneService, 'activatePage' | 'isActive'> & {
|
|
65
|
+
activatePage: NonNullable<ClientApi.OptimizelyOneService['activatePage']>;
|
|
66
|
+
isActive: true;
|
|
67
|
+
})[];
|
|
68
|
+
/**
|
|
69
|
+
* Retrieve all services that must be invoked on the "track page view" step of
|
|
70
|
+
* the execution cycle
|
|
71
|
+
*
|
|
72
|
+
* @returns A list of active services
|
|
73
|
+
*/
|
|
74
|
+
getTrackPageServices: () => (Omit<ClientApi.OptimizelyOneService, 'trackPage' | 'isActive'> & {
|
|
75
|
+
trackPage: NonNullable<ClientApi.OptimizelyOneService['trackPage']>;
|
|
76
|
+
isActive: true;
|
|
77
|
+
})[];
|
|
78
|
+
/**
|
|
79
|
+
* Retrieve an individual service by its code from the collection of services
|
|
80
|
+
*
|
|
81
|
+
* @param code The service code
|
|
82
|
+
* @returns The service, or undefined if it's not part of the collection
|
|
83
|
+
*/
|
|
84
|
+
getService: <SC extends keyof TM>(code: SC) => TM[SC] | undefined;
|
|
85
|
+
};
|
|
86
|
+
declare function useOptimizelyOne(): OptimizelyOneHookResult;
|
|
87
|
+
declare const OptimizelyOneProvider: FunctionComponent<OptimizelyOneProviderProps>;
|
|
88
|
+
export { OptimizelyOneProvider, useOptimizelyOne };
|