@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.
Files changed (139) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +82 -0
  3. package/dist/api/graph-info-service.d.ts +14 -0
  4. package/dist/api/graph-info-service.js +37 -0
  5. package/dist/api/graph-info-service.js.map +1 -0
  6. package/dist/api/index.d.ts +20 -0
  7. package/dist/api/index.js +42 -0
  8. package/dist/api/index.js.map +1 -0
  9. package/dist/api/profile-api-service.d.ts +21 -0
  10. package/dist/api/profile-api-service.js +80 -0
  11. package/dist/api/profile-api-service.js.map +1 -0
  12. package/dist/api/responses.d.ts +2 -0
  13. package/dist/api/responses.js +2 -0
  14. package/dist/api/responses.js.map +1 -0
  15. package/dist/api/types.d.ts +18 -0
  16. package/dist/api/types.js +2 -0
  17. package/dist/api/types.js.map +1 -0
  18. package/dist/api.d.ts +5 -0
  19. package/dist/api.js +4 -0
  20. package/dist/api.js.map +1 -0
  21. package/dist/client-types.d.ts +133 -0
  22. package/dist/client-types.js +2 -0
  23. package/dist/client-types.js.map +1 -0
  24. package/dist/client.d.ts +3 -0
  25. package/dist/client.js +3 -0
  26. package/dist/client.js.map +1 -0
  27. package/dist/components/context.d.ts +88 -0
  28. package/dist/components/context.js +71 -0
  29. package/dist/components/context.js.map +1 -0
  30. package/dist/components/index.d.ts +4 -0
  31. package/dist/components/index.js +5 -0
  32. package/dist/components/index.js.map +1 -0
  33. package/dist/components/optimizely-one-gadget/audiences-panel.d.ts +7 -0
  34. package/dist/components/optimizely-one-gadget/audiences-panel.js +53 -0
  35. package/dist/components/optimizely-one-gadget/audiences-panel.js.map +1 -0
  36. package/dist/components/optimizely-one-gadget/exp-panel.d.ts +3 -0
  37. package/dist/components/optimizely-one-gadget/exp-panel.js +42 -0
  38. package/dist/components/optimizely-one-gadget/exp-panel.js.map +1 -0
  39. package/dist/components/optimizely-one-gadget/graph-panel.d.ts +7 -0
  40. package/dist/components/optimizely-one-gadget/graph-panel.js +27 -0
  41. package/dist/components/optimizely-one-gadget/graph-panel.js.map +1 -0
  42. package/dist/components/optimizely-one-gadget/ids-panel.d.ts +7 -0
  43. package/dist/components/optimizely-one-gadget/ids-panel.js +23 -0
  44. package/dist/components/optimizely-one-gadget/ids-panel.js.map +1 -0
  45. package/dist/components/optimizely-one-gadget/index.d.ts +33 -0
  46. package/dist/components/optimizely-one-gadget/index.js +39 -0
  47. package/dist/components/optimizely-one-gadget/index.js.map +1 -0
  48. package/dist/components/optimizely-one-gadget/interests-panel.d.ts +7 -0
  49. package/dist/components/optimizely-one-gadget/interests-panel.js +23 -0
  50. package/dist/components/optimizely-one-gadget/interests-panel.js.map +1 -0
  51. package/dist/components/optimizely-one-gadget/logo.d.ts +6 -0
  52. package/dist/components/optimizely-one-gadget/logo.js +19 -0
  53. package/dist/components/optimizely-one-gadget/logo.js.map +1 -0
  54. package/dist/components/page-activator.d.ts +4 -0
  55. package/dist/components/page-activator.js +32 -0
  56. package/dist/components/page-activator.js.map +1 -0
  57. package/dist/components/use-test-mode.d.ts +11 -0
  58. package/dist/components/use-test-mode.js +81 -0
  59. package/dist/components/use-test-mode.js.map +1 -0
  60. package/dist/env-vars.d.ts +13 -0
  61. package/dist/env-vars.js +15 -0
  62. package/dist/env-vars.js.map +1 -0
  63. package/dist/products/client-types.d.ts +3 -0
  64. package/dist/products/client-types.js +2 -0
  65. package/dist/products/client-types.js.map +1 -0
  66. package/dist/products/content-recs/api.d.ts +19 -0
  67. package/dist/products/content-recs/api.js +42 -0
  68. package/dist/products/content-recs/api.js.map +1 -0
  69. package/dist/products/content-recs/client.d.ts +10 -0
  70. package/dist/products/content-recs/client.js +29 -0
  71. package/dist/products/content-recs/client.js.map +1 -0
  72. package/dist/products/content-recs/helpers.d.ts +20 -0
  73. package/dist/products/content-recs/helpers.js +27 -0
  74. package/dist/products/content-recs/helpers.js.map +1 -0
  75. package/dist/products/content-recs/index.d.ts +2 -0
  76. package/dist/products/content-recs/index.js +3 -0
  77. package/dist/products/content-recs/index.js.map +1 -0
  78. package/dist/products/data-platform/api.d.ts +41 -0
  79. package/dist/products/data-platform/api.js +116 -0
  80. package/dist/products/data-platform/api.js.map +1 -0
  81. package/dist/products/data-platform/client.d.ts +14 -0
  82. package/dist/products/data-platform/client.js +59 -0
  83. package/dist/products/data-platform/client.js.map +1 -0
  84. package/dist/products/data-platform/helpers.d.ts +22 -0
  85. package/dist/products/data-platform/helpers.js +31 -0
  86. package/dist/products/data-platform/helpers.js.map +1 -0
  87. package/dist/products/data-platform/index.d.ts +10 -0
  88. package/dist/products/data-platform/index.js +10 -0
  89. package/dist/products/data-platform/index.js.map +1 -0
  90. package/dist/products/index.d.ts +3 -0
  91. package/dist/products/index.js +4 -0
  92. package/dist/products/index.js.map +1 -0
  93. package/dist/products/types.d.ts +2 -0
  94. package/dist/products/types.js +2 -0
  95. package/dist/products/types.js.map +1 -0
  96. package/dist/products/web-experimentation/client.d.ts +11 -0
  97. package/dist/products/web-experimentation/client.js +42 -0
  98. package/dist/products/web-experimentation/client.js.map +1 -0
  99. package/dist/products/web-experimentation/helpers.d.ts +13 -0
  100. package/dist/products/web-experimentation/helpers.js +14 -0
  101. package/dist/products/web-experimentation/helpers.js.map +1 -0
  102. package/dist/products/web-experimentation/index.d.ts +1 -0
  103. package/dist/products/web-experimentation/index.js +2 -0
  104. package/dist/products/web-experimentation/index.js.map +1 -0
  105. package/dist/server-components/index.d.ts +1 -0
  106. package/dist/server-components/index.js +2 -0
  107. package/dist/server-components/index.js.map +1 -0
  108. package/dist/server-components/scripts/footer.d.ts +6 -0
  109. package/dist/server-components/scripts/footer.js +11 -0
  110. package/dist/server-components/scripts/footer.js.map +1 -0
  111. package/dist/server-components/scripts/header.d.ts +6 -0
  112. package/dist/server-components/scripts/header.js +12 -0
  113. package/dist/server-components/scripts/header.js.map +1 -0
  114. package/dist/server-components/scripts/index.d.ts +18 -0
  115. package/dist/server-components/scripts/index.js +19 -0
  116. package/dist/server-components/scripts/index.js.map +1 -0
  117. package/dist/server-components/scripts/snippets/optimizely-content-recs.d.ts +6 -0
  118. package/dist/server-components/scripts/snippets/optimizely-content-recs.js +19 -0
  119. package/dist/server-components/scripts/snippets/optimizely-content-recs.js.map +1 -0
  120. package/dist/server-components/scripts/snippets/optimizely-data-patform.d.ts +5 -0
  121. package/dist/server-components/scripts/snippets/optimizely-data-patform.js +37 -0
  122. package/dist/server-components/scripts/snippets/optimizely-data-patform.js.map +1 -0
  123. package/dist/server-components/scripts/snippets/optimizely-web-experimentation.d.ts +5 -0
  124. package/dist/server-components/scripts/snippets/optimizely-web-experimentation.js +9 -0
  125. package/dist/server-components/scripts/snippets/optimizely-web-experimentation.js.map +1 -0
  126. package/dist/server.d.ts +6 -0
  127. package/dist/server.js +11 -0
  128. package/dist/server.js.map +1 -0
  129. package/dist/styles.css +1 -0
  130. package/dist/types.d.ts +2 -0
  131. package/dist/types.js +2 -0
  132. package/dist/types.js.map +1 -0
  133. package/dist/utils/env.d.ts +11 -0
  134. package/dist/utils/env.js +49 -0
  135. package/dist/utils/env.js.map +1 -0
  136. package/dist/utils/session.d.ts +11 -0
  137. package/dist/utils/session.js +28 -0
  138. package/dist/utils/session.js.map +1 -0
  139. 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,2 @@
1
+ import type { ApiServiceErrorResponse } from "./types";
2
+ export declare const NotFound: ApiServiceErrorResponse;
@@ -0,0 +1,2 @@
1
+ export const NotFound = [{ error: { status: 404, message: "Not found" } }, 404];
2
+ //# sourceMappingURL=responses.js.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":""}
package/dist/api.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export type { OptimizelyOneApiConfig } from './api/index';
2
+ export type * from './products/types';
3
+ export { createOptimizelyOneApi } from './api/index';
4
+ export * from './products';
5
+ export * as Session from './utils/session';
package/dist/api.js ADDED
@@ -0,0 +1,4 @@
1
+ export { createOptimizelyOneApi } from './api/index';
2
+ export * from './products';
3
+ export * as Session from './utils/session';
4
+ //# sourceMappingURL=api.js.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=client-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-types.js","sourceRoot":"","sources":["../src/client-types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export type * from './products/client-types';
2
+ export * from './products';
3
+ export * from './components';
package/dist/client.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from './products'; // Product libraries work across client & server
2
+ export * from './components'; // Client component hooks
3
+ //# sourceMappingURL=client.js.map
@@ -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 };