@remkoj/optimizely-cms-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 (54) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +2 -0
  3. package/dist/auth.d.ts +73 -0
  4. package/dist/auth.js +154 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/client.d.ts +8 -0
  7. package/dist/client.js +22 -0
  8. package/dist/client.js.map +1 -0
  9. package/dist/cms-page/data.d.ts +39 -0
  10. package/dist/cms-page/data.js +43 -0
  11. package/dist/cms-page/data.js.map +1 -0
  12. package/dist/cms-page/index.d.ts +5 -0
  13. package/dist/cms-page/index.js +3 -0
  14. package/dist/cms-page/index.js.map +1 -0
  15. package/dist/cms-page/layout.d.ts +16 -0
  16. package/dist/cms-page/layout.js +81 -0
  17. package/dist/cms-page/layout.js.map +1 -0
  18. package/dist/cms-page/page.d.ts +28 -0
  19. package/dist/cms-page/page.js +108 -0
  20. package/dist/cms-page/page.js.map +1 -0
  21. package/dist/cms-page/utils.d.ts +5 -0
  22. package/dist/cms-page/utils.js +19 -0
  23. package/dist/cms-page/utils.js.map +1 -0
  24. package/dist/components/on-page-edit.d.ts +24 -0
  25. package/dist/components/on-page-edit.js +85 -0
  26. package/dist/components/on-page-edit.js.map +1 -0
  27. package/dist/index.d.ts +7 -0
  28. package/dist/index.js +8 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/metadata.d.ts +18 -0
  31. package/dist/metadata.js +36 -0
  32. package/dist/metadata.js.map +1 -0
  33. package/dist/ope/data.d.ts +2 -0
  34. package/dist/ope/data.js +28 -0
  35. package/dist/ope/data.js.map +1 -0
  36. package/dist/ope/index.d.ts +4 -0
  37. package/dist/ope/index.js +5 -0
  38. package/dist/ope/index.js.map +1 -0
  39. package/dist/ope/page.d.ts +17 -0
  40. package/dist/ope/page.js +141 -0
  41. package/dist/ope/page.js.map +1 -0
  42. package/dist/ope/types.d.ts +73 -0
  43. package/dist/ope/types.js +2 -0
  44. package/dist/ope/types.js.map +1 -0
  45. package/dist/page.d.ts +2 -0
  46. package/dist/page.js +6 -0
  47. package/dist/page.js.map +1 -0
  48. package/dist/publish/index.d.ts +10 -0
  49. package/dist/publish/index.js +54 -0
  50. package/dist/publish/index.js.map +1 -0
  51. package/dist/types.d.ts +6 -0
  52. package/dist/types.js +2 -0
  53. package/dist/types.js.map +1 -0
  54. package/package.json +63 -0
@@ -0,0 +1,5 @@
1
+ import type { ChannelDefinition } from "@remkoj/optimizely-graph-client";
2
+ export declare function urlToPath(baseUrl: URL, language: string): string[];
3
+ export declare function localeToGraphLocale(channel: ChannelDefinition, locale: string): string;
4
+ export declare function slugToLocale<T extends string | undefined | null>(channel: ChannelDefinition, slug: string, defaultValue: T): string | T;
5
+ export declare function slugToGraphLocale<T extends string | undefined | null>(channel: ChannelDefinition, slug: string, defaultValue: T): string | T;
@@ -0,0 +1,19 @@
1
+ // Extract the path as string array from a given URL
2
+ export function urlToPath(baseUrl, language) {
3
+ let slugs = baseUrl.pathname.split('/').filter(s => s);
4
+ if (slugs[0] == language)
5
+ slugs.shift();
6
+ return slugs;
7
+ }
8
+ export function localeToGraphLocale(channel, locale) {
9
+ return channel.localeToGraphLocale(locale) ?? locale.replaceAll("-", "_");
10
+ }
11
+ export function slugToLocale(channel, slug, defaultValue) {
12
+ const route = channel.locales.filter(x => x.slug == slug)[0];
13
+ return route?.code || defaultValue;
14
+ }
15
+ export function slugToGraphLocale(channel, slug, defaultValue) {
16
+ const route = channel.locales.filter(x => x.slug == slug)[0];
17
+ return route?.graphLocale || defaultValue?.replaceAll("-", "_");
18
+ }
19
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/cms-page/utils.ts"],"names":[],"mappings":"AAEA,oDAAoD;AACpD,MAAM,UAAU,SAAS,CAAC,OAAY,EAAE,QAAgB;IACpD,IAAI,KAAK,GAAc,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IACjE,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,QAAQ;QACpB,KAAK,CAAC,KAAK,EAAE,CAAA;IACjB,OAAO,KAAK,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAA0B,EAAE,MAAc;IAE1E,OAAO,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,EAAC,GAAG,CAAC,CAAA;AAC5E,CAAC;AAED,MAAM,UAAU,YAAY,CAAsC,OAA0B,EAAE,IAAY,EAAE,YAAe;IAEvH,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IAC5D,OAAO,KAAK,EAAE,IAAI,IAAI,YAAY,CAAA;AACtC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAsC,OAA0B,EAAE,IAAY,EAAE,YAAe;IAE5H,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IAC5D,OAAO,KAAK,EAAE,WAAW,IAAI,YAAY,EAAE,UAAU,CAAC,GAAG,EAAC,GAAG,CAAM,CAAA;AACvE,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { type FunctionComponent, type PropsWithChildren } from 'react';
2
+ export type OnPageEditProps = PropsWithChildren<{
3
+ mode?: 'edit' | 'preview';
4
+ className?: string;
5
+ timeout?: number;
6
+ }>;
7
+ export type OptimizelyCmsContext = {
8
+ ready: boolean;
9
+ inEditMode: boolean;
10
+ isEditable: boolean;
11
+ subscribe: (event: string, handler: (...args: any) => void) => void;
12
+ };
13
+ export type OptimizelyCmsContentSavedEvent = {
14
+ contentLink: string;
15
+ editUrl: string;
16
+ previewUrl: string;
17
+ };
18
+ declare global {
19
+ interface Window {
20
+ epi?: OptimizelyCmsContext;
21
+ }
22
+ }
23
+ export declare const OnPageEdit: FunctionComponent<OnPageEditProps>;
24
+ export default OnPageEdit;
@@ -0,0 +1,85 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState, useEffect } from 'react';
4
+ import { useRouter } from 'next/navigation';
5
+ const DEV = process.env.NODE_ENV == 'development';
6
+ export const OnPageEdit = ({ mode, children, className, timeout }) => {
7
+ const router = useRouter();
8
+ const [optiCmsReady, setOptiCmsReady] = useState(false);
9
+ const [showMask, setShowMask] = useState(false);
10
+ timeout = timeout ?? 1500;
11
+ // Bind to the CMS & CMS Ready State
12
+ useEffect(() => {
13
+ console.log("Reading Opti CMS Context");
14
+ const fxCms = tryGetCms();
15
+ const cmsReady = fxCms?.ready ?? false;
16
+ setOptiCmsReady(cmsReady);
17
+ if (!cmsReady) {
18
+ const cancelToken = setInterval(() => {
19
+ const updateCms = tryGetCms();
20
+ const updatedCmsReady = updateCms?.ready ?? false;
21
+ if (updatedCmsReady) {
22
+ clearInterval(cancelToken);
23
+ setOptiCmsReady(updatedCmsReady);
24
+ }
25
+ }, 250);
26
+ return () => {
27
+ clearInterval(cancelToken);
28
+ };
29
+ }
30
+ }, []);
31
+ // Bind to the Saved event
32
+ useEffect(() => {
33
+ if (!optiCmsReady)
34
+ return;
35
+ const previewUrl = window.location.href;
36
+ let handlerEnabled = true;
37
+ // Define event handler
38
+ let maskTimer = false;
39
+ function onContentSaved(eventData) {
40
+ setShowMask(true);
41
+ if (maskTimer != false)
42
+ clearTimeout(maskTimer);
43
+ console.log(`Delaying refresh with ${timeout}ms to allow Optimizely Graph to update`);
44
+ maskTimer = setTimeout(() => {
45
+ const contentId = window.location.pathname.split(',,')[1];
46
+ const newContentId = eventData.contentLink;
47
+ if (previewUrl == eventData.previewUrl) {
48
+ console.log(`Refreshing preview: ${contentId} => ${newContentId}`);
49
+ router.refresh();
50
+ //setShowMask(false)
51
+ }
52
+ else {
53
+ const newUrl = new URL(eventData.previewUrl);
54
+ console.log(`Navigating to new preview: ${contentId} => ${newContentId}`);
55
+ router.push(newUrl.pathname + newUrl.search);
56
+ setShowMask(false);
57
+ }
58
+ }, timeout);
59
+ }
60
+ // Subscribe to event
61
+ console.log(`Subscribing to ContentSaved Event`);
62
+ const opti = tryGetCms();
63
+ opti?.subscribe('contentSaved', (eventData) => {
64
+ if (!handlerEnabled)
65
+ return;
66
+ onContentSaved(eventData);
67
+ });
68
+ // Unsubscribe when needed
69
+ return () => {
70
+ console.log(`Navigating away, disabling ContentSaved event handler`);
71
+ handlerEnabled = false;
72
+ };
73
+ }, [optiCmsReady, router, timeout]);
74
+ return _jsx(_Fragment, { children: showMask && _jsx("div", { className: `loading-mask ${className}`.trimEnd(), children: children }) });
75
+ };
76
+ function tryGetCms() {
77
+ try {
78
+ return window.epi;
79
+ }
80
+ catch {
81
+ return undefined;
82
+ }
83
+ }
84
+ export default OnPageEdit;
85
+ //# sourceMappingURL=on-page-edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"on-page-edit.js","sourceRoot":"","sources":["../../src/components/on-page-edit.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export * from './client';
2
+ export * from './metadata';
3
+ export * from './types';
4
+ export * from './page';
5
+ export * as Auth from './auth';
6
+ export * as OnPageEdit from './ope';
7
+ export * as CmsPage from './cms-page';
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export * from './client';
2
+ export * from './metadata';
3
+ export * from './types';
4
+ export * from './page';
5
+ export * as Auth from './auth';
6
+ export * as OnPageEdit from './ope';
7
+ export * as CmsPage from './cms-page';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAA;AAC9B,OAAO,KAAK,UAAU,MAAM,OAAO,CAAA;AACnC,OAAO,KAAK,OAAO,MAAM,YAAY,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { type ComponentFactory, type ContentLink } from '@remkoj/optimizely-cms-react';
2
+ import { type OptimizelyGraphConfig, type IOptiGraphClient } from '@remkoj/optimizely-graph-client';
3
+ import { Metadata } from 'next';
4
+ export declare class MetaDataResolver {
5
+ private _cgClient;
6
+ constructor(clientOrConfig?: OptimizelyGraphConfig | IOptiGraphClient);
7
+ /**
8
+ * Resolve the meta data for a component, if it has a meta-data method exposed.
9
+ *
10
+ * @param factory The component factory used to load the component
11
+ * @param contentLink The link to the component for which the meta-data should be retrieved
12
+ * @param contentType The content type of the component
13
+ * @param locale The locale to be used, in a ContentGraph locale format
14
+ * @returns A Promise for the metadata of the given content type & instance
15
+ */
16
+ resolve(factory: ComponentFactory, contentLink: ContentLink, contentType: string[], locale: string): Promise<Metadata>;
17
+ }
18
+ export default MetaDataResolver;
@@ -0,0 +1,36 @@
1
+ import createClient, { isContentGraphClient } from '@remkoj/optimizely-graph-client';
2
+ import { isOptimizelyNextPageWithMetaData } from './page';
3
+ const DEBUG = process.env.DXP_DEBUG == '1';
4
+ export class MetaDataResolver {
5
+ _cgClient;
6
+ constructor(clientOrConfig) {
7
+ this._cgClient = isContentGraphClient(clientOrConfig) ? clientOrConfig : createClient(clientOrConfig);
8
+ }
9
+ /**
10
+ * Resolve the meta data for a component, if it has a meta-data method exposed.
11
+ *
12
+ * @param factory The component factory used to load the component
13
+ * @param contentLink The link to the component for which the meta-data should be retrieved
14
+ * @param contentType The content type of the component
15
+ * @param locale The locale to be used, in a ContentGraph locale format
16
+ * @returns A Promise for the metadata of the given content type & instance
17
+ */
18
+ async resolve(factory, contentLink, contentType, locale) {
19
+ if (DEBUG)
20
+ console.log("[MetaDataResolver] Resolving metadata for:", contentLink, contentType, locale);
21
+ if (locale.includes("-"))
22
+ throw new Error("Invalid character detected within the locale");
23
+ const Component = factory.resolve(contentType);
24
+ if (!Component)
25
+ return {};
26
+ if (isOptimizelyNextPageWithMetaData(Component) && Component.getMetaData) {
27
+ const meta = await Component.getMetaData(contentLink, locale, this._cgClient);
28
+ if (DEBUG)
29
+ console.log("[MetaDataResolver] Resolved metadata to:", meta);
30
+ return meta;
31
+ }
32
+ return {};
33
+ }
34
+ }
35
+ export default MetaDataResolver;
36
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,EAAE,EAAE,oBAAoB,EAAqD,MAAM,iCAAiC,CAAA;AAEvI,OAAO,EAAE,gCAAgC,EAAE,MAAM,QAAQ,CAAA;AAEzD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,GAAG,CAAA;AAE1C,MAAM,OAAO,gBAAgB;IAEjB,SAAS,CAAmB;IAEpC,YAAmB,cAAyD;QAExE,IAAI,CAAC,SAAS,GAAG,oBAAoB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC,cAAc,CAAC,CAAA;IACzG,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,OAAO,CAAC,OAAyB,EAAE,WAAwB,EAAE,WAAqB,EAAE,MAAc;QAE3G,IAAI,KAAK;YACL,OAAO,CAAC,GAAG,CAAC,4CAA4C,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,CAAA;QAE/F,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;QAEnE,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;QAC9C,IAAI,CAAC,SAAS;YACV,OAAO,EAAE,CAAA;QAEb,IAAI,gCAAgC,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC;YACvE,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;YAC7E,IAAI,KAAK;gBACL,OAAO,CAAC,GAAG,CAAC,0CAA0C,EAAE,IAAI,CAAC,CAAA;YACjE,OAAO,IAAI,CAAA;QACf,CAAC;QACD,OAAO,EAAE,CAAA;IACb,CAAC;CACJ;AAED,eAAe,gBAAgB,CAAA"}
@@ -0,0 +1,2 @@
1
+ import type { GetContentByIdMethod } from './types';
2
+ export declare const getContentById: GetContentByIdMethod;
@@ -0,0 +1,28 @@
1
+ import { gql } from 'graphql-request';
2
+ export const getContentById = async (client, variables) => {
3
+ return await client.request(gqlQuery, variables);
4
+ };
5
+ const gqlQuery = gql `query getContentByIdBase($id: Int, $workId: Int, $guidValue: String, $locale: [Locales!], $isCommonDraft: Boolean) {
6
+ Content(
7
+ where: {
8
+ ContentLink: { Id: { eq: $id }, WorkId: { eq: $workId }, GuidValue: { eq: $guidValue } }
9
+ IsCommonDraft: { eq: $isCommonDraft }
10
+ }
11
+ locale: $locale
12
+ ) {
13
+ total
14
+ items {
15
+ contentType: ContentType
16
+ id: ContentLink {
17
+ id: Id
18
+ workId: WorkId
19
+ guidValue: GuidValue
20
+ }
21
+ locale: Language {
22
+ name: Name
23
+ }
24
+ path: RelativePath
25
+ }
26
+ }
27
+ }`;
28
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sourceRoot":"","sources":["../../src/ope/data.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAA;AAErC,MAAM,CAAC,MAAM,cAAc,GAA0B,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE;IAE7E,OAAO,MAAM,MAAM,CAAC,OAAO,CAA8C,QAAQ,EAAE,SAAS,CAAC,CAAA;AACjG,CAAC,CAAA;AAED,MAAM,QAAQ,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;EAsBlB,CAAA"}
@@ -0,0 +1,4 @@
1
+ import 'server-only';
2
+ export * as Types from './types';
3
+ export * from './page';
4
+ export { createEditPageComponent as default } from './page';
@@ -0,0 +1,5 @@
1
+ import 'server-only';
2
+ export * as Types from './types';
3
+ export * from './page';
4
+ export { createEditPageComponent as default } from './page';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ope/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,OAAO,KAAK,KAAK,MAAM,SAAS,CAAA;AAChC,cAAc,QAAQ,CAAA;AACtB,OAAO,EAAE,uBAAuB,IAAI,OAAO,EAAE,MAAM,QAAQ,CAAA"}
@@ -0,0 +1,17 @@
1
+ import 'server-only';
2
+ import type { EditPageComponent, EditViewOptions } from './types';
3
+ import { type Services } from '@remkoj/optimizely-graph-client';
4
+ import { type ComponentFactory } from '@remkoj/optimizely-cms-react/rsc';
5
+ /**
6
+ * Create the EditPage component needed by Next.JS to render the "On Page
7
+ * Editing" variant of the content item selected by the editor.
8
+ *
9
+ * @param dxpUrl The domain of the CMS instance
10
+ * @param client The Apollo GraphQL client to use
11
+ * @param channel The static site definition to use
12
+ * @param factory The component factory to be used
13
+ * @param options The optional options to use to control the edit page
14
+ * @returns The React Component that can be used by Next.JS to render the page
15
+ */
16
+ export declare function createEditPageComponent(channel: Readonly<Services.ChannelDefinition>, factory: ComponentFactory, options?: Partial<EditViewOptions>): EditPageComponent;
17
+ export default createEditPageComponent;
@@ -0,0 +1,141 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import 'server-only';
3
+ import { AuthMode } from '@remkoj/optimizely-graph-client';
4
+ import { Utils } from '@remkoj/optimizely-cms-react';
5
+ import { CmsContent, getServerContext } from '@remkoj/optimizely-cms-react/rsc';
6
+ import { notFound } from 'next/navigation';
7
+ import OnPageEdit from '../components/on-page-edit';
8
+ import { getAuthorizedServerClient } from '../client';
9
+ import React from 'react';
10
+ import Script from 'next/script';
11
+ import { getContentById } from './data';
12
+ const defaultOptions = {
13
+ refreshDelay: 2000,
14
+ refreshNotice: () => _jsx("div", { className: 'optly-refresh-notice', children: "Updating preview, please wait...." }),
15
+ errorNotice: props => _jsxs("div", { className: 'optly-error-notice', children: [_jsx("div", { className: 'optly-error-title', children: props.title }), _jsx("div", { className: 'optly-error-message', children: props.message })] }),
16
+ layout: props => _jsx("div", { className: 'optly-edit-page', "data-locale": props.locale, children: props.children }),
17
+ loader: getContentById,
18
+ clientFactory: (token) => getAuthorizedServerClient(token)
19
+ };
20
+ /**
21
+ * Create the EditPage component needed by Next.JS to render the "On Page
22
+ * Editing" variant of the content item selected by the editor.
23
+ *
24
+ * @param dxpUrl The domain of the CMS instance
25
+ * @param client The Apollo GraphQL client to use
26
+ * @param channel The static site definition to use
27
+ * @param factory The component factory to be used
28
+ * @param options The optional options to use to control the edit page
29
+ * @returns The React Component that can be used by Next.JS to render the page
30
+ */
31
+ export function createEditPageComponent(channel, factory, options) {
32
+ const { layout: PageLayout, refreshNotice: RefreshNotice, refreshDelay, errorNotice: ErrorNotice, loader: getContentById, clientFactory } = { ...defaultOptions, ...options };
33
+ const dxpUrl = channel.getCmsUrl();
34
+ async function EditPage({ params, searchParams }) {
35
+ // Create context
36
+ const context = getServerContext();
37
+ // Validate the search parameters
38
+ const epiEditMode = searchParams?.epieditmode?.toLowerCase();
39
+ if (epiEditMode != 'true' && epiEditMode != 'false') {
40
+ console.error("[OnPageEdit] Edit mode requested without valid EpiEditMode, refused to render the page. Mode set:", searchParams.epieditmode);
41
+ return notFound();
42
+ }
43
+ // Allow use-hmac as magic token to be used only on a development environment, otherwise require a minimal length string as token
44
+ const token = searchParams.preview_token;
45
+ const validDev = context.isDevelopment && (searchParams.preview_token == AuthMode.HMAC || searchParams.preview_token == AuthMode.Basic);
46
+ if (!token || (token.length < 20 && !validDev)) {
47
+ console.error("[OnPageEdit] Edit mode requested without valid Preview Token, refused to render the page");
48
+ return notFound();
49
+ }
50
+ if (context.isDebug)
51
+ console.log(`[OnPageEdit] Valid edit mode request: EpiEditMode=${searchParams.epieditmode}`);
52
+ // Helper function to read the ContentID & WorkID
53
+ function getContentIds() {
54
+ try {
55
+ // When using HMAC authentication, fall back to information in the URL
56
+ if (validDev) {
57
+ const contentString = slugs.join('/').split(',,').pop() ?? '';
58
+ const [contentId, workId] = contentString.split('_', 3);
59
+ return [Number.parseInt(contentId), workId ? Number.parseInt(workId) : null];
60
+ }
61
+ // Normally take the information from the token
62
+ const jwt = JSON.parse(Buffer.from((token || '..').split('.', 3)[1], 'base64').toString());
63
+ const contentId = Number.parseInt(jwt?.c_id || '-1', 10);
64
+ const workId = Number.parseInt(jwt?.c_ver || '0') || null;
65
+ if ((jwt.exp * 1000) < Date.now())
66
+ console.warn("[OnPageEdit] Token has expired, it is unlikely that you are able to fetch content with it");
67
+ return [contentId, workId];
68
+ }
69
+ catch {
70
+ return [-1, null];
71
+ }
72
+ }
73
+ // Build context
74
+ const client = clientFactory(token);
75
+ context.setOptimizelyGraphClient(client);
76
+ context.setComponentFactory(factory);
77
+ context.setInEditMode(epiEditMode == 'true');
78
+ // Get information from the Request URI
79
+ const requestPath = ('/' + params.path.map(decodeURIComponent).join('/')).replace(/^(\/ui){0,1}(\/cms){0,1}(\/content){0,1}\//i, '');
80
+ const slugs = requestPath.split('/');
81
+ const locale = channel.locales.some(x => x.slug == slugs[0]) ? slugs[0] : channel.defaultLocale;
82
+ if (context.isDebug)
83
+ console.log(`[OnPageEdit] Inferred content locale from path: ${locale}`);
84
+ const [contentId, workId] = getContentIds();
85
+ context.setLocale(channel.localeToGraphLocale(locale));
86
+ const contentLink = {
87
+ id: contentId,
88
+ workId: workId,
89
+ guidValue: null,
90
+ locale: locale
91
+ };
92
+ const variables = {
93
+ ...contentLink,
94
+ locale: contentLink.locale,
95
+ isCommonDraft: !contentLink.workId ? true : null
96
+ };
97
+ if (context.isDebug) {
98
+ console.log("[OnPageEdit] Requested content:", JSON.stringify(variables));
99
+ console.log("[OnPageEdit] Creating GraphQL Client:", token);
100
+ }
101
+ try {
102
+ const contentInfo = await getContentById(client, variables);
103
+ const contentItem = (contentInfo?.Content?.items ?? [])[0];
104
+ const contentType = Utils.normalizeContentType(contentItem?.contentType);
105
+ // Return a 404 if the content item or type could not be resolved
106
+ if (!contentItem) {
107
+ console.warn(`[OnPageEdit] The content item for ${JSON.stringify(variables)} could not be loaded from Optimizely Graph`);
108
+ return notFound();
109
+ }
110
+ if (!contentType) {
111
+ console.warn(`[OnPageEdit] The content item for ${JSON.stringify(variables)} did not contain content type information`);
112
+ return notFound();
113
+ }
114
+ if (context.isDebug) {
115
+ const contentItemId = contentItem?.id;
116
+ console.log("[OnPageEdit] Resolved content:", JSON.stringify({
117
+ id: contentItemId?.id,
118
+ workId: contentItemId?.workId,
119
+ guidValue: contentItemId?.guidValue,
120
+ locale: contentItem.locale?.name,
121
+ type: (contentItem.contentType ?? []).slice(0, -1).join('/')
122
+ }));
123
+ }
124
+ // Store the editable content so it can be tested
125
+ context.setEditableContentId(contentLink);
126
+ // Render the content, with edit mode context
127
+ const isPage = contentItem.contentType?.some(x => x?.toLowerCase() == "page") ?? false;
128
+ const loadedContentId = Utils.normalizeContentLinkWithLocale({ ...contentItem?.id, locale: contentItem?.locale?.name });
129
+ const Layout = isPage ? PageLayout : React.Fragment;
130
+ const output = _jsxs(_Fragment, { children: [context.inEditMode && _jsx(Script, { src: `${dxpUrl}/ui/CMS/latest/clientresources/communicationinjector.js`, strategy: 'afterInteractive' }), _jsxs(Layout, { locale: locale, children: [_jsx(OnPageEdit, { timeout: refreshDelay, mode: context.inEditMode ? 'edit' : 'preview', className: 'bg-slate-900 absolute top-0 left-0 w-screen h-screen opacity-60 z-50', children: _jsx(RefreshNotice, {}) }), _jsx(CmsContent, { contentType: contentType, contentLink: contentLink, fragmentData: contentItem })] }), _jsxs("div", { className: 'optly-contentLink', children: ["ID: ", loadedContentId?.id ?? "-", " | Version: ", loadedContentId?.workId ?? "-", " | Global ID: ", loadedContentId?.guidValue ?? "-", " | Locale: ", loadedContentId?.locale ?? ""] })] });
131
+ return output;
132
+ }
133
+ catch (e) {
134
+ console.error("[OnPageEdit] Caught error", e);
135
+ return notFound();
136
+ }
137
+ }
138
+ return EditPage;
139
+ }
140
+ export default createEditPageComponent;
141
+ //# sourceMappingURL=page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/ope/page.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import type { ComponentType, PropsWithChildren } from 'react';
2
+ import type { ClientFactory } from '@remkoj/optimizely-graph-client';
3
+ import type { GraphQLClient } from 'graphql-request';
4
+ type ServerPageProps = {
5
+ params: Record<string, string | Array<string>>;
6
+ searchParams: Record<string, string>;
7
+ };
8
+ export type EditPageComponent<T extends ServerPageProps = EditPageProps> = ({ params, searchParams }: T) => Promise<JSX.Element>;
9
+ export type EditPageProps = {
10
+ params: {
11
+ path: string[];
12
+ };
13
+ searchParams: Partial<{
14
+ epieditmode: string;
15
+ preview_token: string;
16
+ }>;
17
+ };
18
+ export type EditViewOptions = {
19
+ /**
20
+ * The number of miliseconds to wait between receiving the 'dataSaved'
21
+ * event from the Optimizely CMS and actually refreshing the preview.
22
+ */
23
+ refreshDelay: number;
24
+ /**
25
+ * The message to show to the editor when awaiting the data to be updated
26
+ * in ContentGraph
27
+ */
28
+ refreshNotice: ComponentType<{}>;
29
+ /**
30
+ * The message to show to the editor when an error occured in rendering the
31
+ * on page editing mode
32
+ */
33
+ errorNotice: ComponentType<{
34
+ title: string;
35
+ message: string;
36
+ }>;
37
+ /**
38
+ * The layout to use when rendering a page component
39
+ */
40
+ layout: ComponentType<PropsWithChildren<{
41
+ locale: string;
42
+ }>>;
43
+ /**
44
+ * The base content loader to be used for the edit view
45
+ */
46
+ loader: GetContentByIdMethod;
47
+ clientFactory: ClientFactory;
48
+ };
49
+ export type GetContentByIdVariables = {
50
+ id?: number;
51
+ workId?: number | null;
52
+ guidValue?: string | null;
53
+ locale?: string | Array<string>;
54
+ isCommonDraft?: boolean | null;
55
+ };
56
+ export type GetContentByIdData = {
57
+ Content: {
58
+ items: {
59
+ contentType?: Array<string | null> | null;
60
+ id: {
61
+ id?: number | null;
62
+ workId?: number | null;
63
+ guidValue?: string | null;
64
+ };
65
+ locale?: {
66
+ name?: string | null;
67
+ } | null;
68
+ path?: string | null;
69
+ }[];
70
+ };
71
+ };
72
+ export type GetContentByIdMethod = (client: GraphQLClient, variables: GetContentByIdVariables) => Promise<GetContentByIdData>;
73
+ export {};
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/ope/types.ts"],"names":[],"mappings":""}
package/dist/page.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type { OptimizelyNextPage } from "./types";
2
+ export declare function isOptimizelyNextPageWithMetaData(toTest: any): toTest is OptimizelyNextPage;
package/dist/page.js ADDED
@@ -0,0 +1,6 @@
1
+ export function isOptimizelyNextPageWithMetaData(toTest) {
2
+ if ((typeof (toTest) != 'function' && typeof (toTest) != 'object') || toTest == null)
3
+ return false;
4
+ return toTest?.getMetaData ? true : false;
5
+ }
6
+ //# sourceMappingURL=page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.js","sourceRoot":"","sources":["../src/page.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gCAAgC,CAAC,MAAW;IAExD,IAAI,CAAC,OAAM,CAAC,MAAM,CAAC,IAAI,UAAU,IAAI,OAAM,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAI,MAAM,IAAI,IAAI;QAC9E,OAAO,KAAK,CAAA;IAEhB,OAAQ,MAA6B,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAA;AACrE,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type NextRequest, NextResponse } from 'next/server';
2
+ import { type IOptiGraphClient } from "@remkoj/optimizely-graph-client";
3
+ export type PublishApiResponse = {
4
+ status: "success" | "no-publish";
5
+ paths?: string[];
6
+ } | {
7
+ error: string;
8
+ };
9
+ export declare function createPublishApi(client?: IOptiGraphClient): (req: NextRequest) => Promise<NextResponse<PublishApiResponse>>;
10
+ export default createPublishApi;
@@ -0,0 +1,54 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { getServerClient } from '../client';
3
+ import { revalidatePath } from 'next/cache';
4
+ const editPaths = ['/ui/[[...path]]'];
5
+ const publishedPaths = ['/[lang]', '/[lang]/[[...path]]', '/sitemap', '/sitemap.xml'];
6
+ const paths = [...editPaths, ...publishedPaths];
7
+ export function createPublishApi(client) {
8
+ const graphClient = client ?? getServerClient();
9
+ function tryJsonParse(data) {
10
+ if (typeof (data) != 'string')
11
+ return null;
12
+ try {
13
+ return JSON.parse(data);
14
+ }
15
+ catch {
16
+ return null;
17
+ }
18
+ }
19
+ const publishHandler = async (req) => {
20
+ // Validate access
21
+ const xAuthToken = req.headers.get("X-OPTLY-PUBLISH") ??
22
+ req.nextUrl.searchParams.get("token") ??
23
+ undefined;
24
+ const serverToken = graphClient.siteInfo.publishToken;
25
+ if (!serverToken || serverToken == "") {
26
+ console.error("No authentication configured, publishing has been disabled");
27
+ return NextResponse.json({ error: "Not authorized" }, { status: 401 });
28
+ }
29
+ if (serverToken != xAuthToken) {
30
+ console.error("[Publish-API] The provided publishing token is invalid", xAuthToken);
31
+ return NextResponse.json({ error: "Not authorized" }, { status: 401 });
32
+ }
33
+ // Get request data
34
+ const requestBody = tryJsonParse(await req.text());
35
+ // Don't publish if we're in selective mode and there's no data
36
+ if (!requestBody) {
37
+ console.log("Not flushing due to missing request body");
38
+ return NextResponse.json({ status: "no-publish" });
39
+ }
40
+ const action = requestBody.type?.action;
41
+ const subject = requestBody.type?.subject;
42
+ // Only publish on updated documents
43
+ if (subject != "doc" || action != "updated") {
44
+ console.log("Not flushing due to incorrect subject or type", JSON.stringify(requestBody));
45
+ return NextResponse.json({ status: "no-publish" });
46
+ }
47
+ paths.forEach(p => revalidatePath(p, 'page'));
48
+ console.log("Publishing => Revalidated (paths)", paths);
49
+ return NextResponse.json({ status: "success", paths });
50
+ };
51
+ return publishHandler;
52
+ }
53
+ export default createPublishApi;
54
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/publish/index.ts"],"names":[],"mappings":"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"}