@enonic/nextjs-adapter 0.10.1 → 0.11.0

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.
@@ -14,14 +14,14 @@ export interface ComponentDefinition {
14
14
  processor?: DataProcessor;
15
15
  view?: React.FunctionComponent<any>;
16
16
  }
17
- export declare type DataProcessor = (data: any, context?: Context) => Promise<Record<string, any>>;
18
- export declare type VariablesGetter = (path: string, context?: Context, config?: any) => VariablesGetterResult;
19
- export declare type QueryGetter = (config?: any) => string;
20
- export declare type VariablesGetterResult = {
17
+ export type DataProcessor = (data: any, context?: Context) => Promise<Record<string, any>>;
18
+ export type VariablesGetter = (path: string, context?: Context, config?: any) => VariablesGetterResult;
19
+ export type QueryGetter = (config?: any) => string;
20
+ export type VariablesGetterResult = {
21
21
  [variables: string]: any;
22
22
  path: string;
23
23
  };
24
- export declare type SelectedQueryMaybeVariablesFunc = string | QueryGetter | {
24
+ export type SelectedQueryMaybeVariablesFunc = string | QueryGetter | {
25
25
  query: string | QueryGetter;
26
26
  variables: VariablesGetter;
27
27
  } | [
@@ -7,7 +7,7 @@ import { ParsedUrlQuery } from 'node:querystring';
7
7
  import { type GetServerSidePropsContext } from 'next';
8
8
  import { IncomingMessage } from 'http';
9
9
  import { type NextApiRequestCookies } from 'next/dist/server/api-utils';
10
- export declare type AdapterConstants = {
10
+ export type AdapterConstants = {
11
11
  APP_NAME: string;
12
12
  APP_NAME_DASHED: string;
13
13
  SITE_KEY: string;
@@ -15,22 +15,22 @@ export declare type AdapterConstants = {
15
15
  getRenderMode: (context?: Context) => RENDER_MODE;
16
16
  getSingleComponentPath: (context?: Context) => string | undefined;
17
17
  };
18
- declare type Result = {
18
+ type Result = {
19
19
  error?: {
20
20
  code: string;
21
21
  message: string;
22
22
  } | null;
23
23
  };
24
- declare type GuillotineResult = Result & {
24
+ type GuillotineResult = Result & {
25
25
  [dataKey: string]: any;
26
26
  };
27
- export declare type FetchContentResult = Result & {
27
+ export type FetchContentResult = Result & {
28
28
  data: Record<string, any> | null;
29
29
  common: Record<string, any> | null;
30
30
  meta: MetaData;
31
31
  page: PageComponent | null;
32
32
  };
33
- declare type FetcherConfig<T extends AdapterConstants> = T & {
33
+ type FetcherConfig<T extends AdapterConstants> = T & {
34
34
  componentRegistry: typeof ComponentRegistry;
35
35
  };
36
36
  export interface ServerSideParams extends ParsedUrlQuery {
@@ -41,7 +41,7 @@ export interface PreviewParams {
41
41
  contentPath: string[];
42
42
  headers: Record<string, string>;
43
43
  }
44
- export declare type Context = GetServerSidePropsContext<ServerSideParams, PreviewParams>;
44
+ export type Context = GetServerSidePropsContext<ServerSideParams, PreviewParams>;
45
45
  export interface MinimalContext {
46
46
  req: IncomingMessage & {
47
47
  cookies: NextApiRequestCookies;
@@ -52,17 +52,17 @@ export interface MinimalContext {
52
52
  * @param contentPath string or string array: pre-split or slash-delimited _path to a content available on the API
53
53
  * @returns FetchContentResult object: {data?: T, error?: {code, message}}
54
54
  */
55
- export declare type ContentFetcher = (contentPath: string | string[], context: Context) => Promise<FetchContentResult>;
56
- export declare type ContentApiBaseBody = {
55
+ export type ContentFetcher = (contentPath: string | string[], context: Context) => Promise<FetchContentResult>;
56
+ export type ContentApiBaseBody = {
57
57
  query?: string;
58
58
  variables?: {
59
59
  path?: string;
60
60
  };
61
61
  };
62
62
  /** Generic fetch */
63
- export declare const fetchFromApi: (apiUrl: string, body: {}, method?: string) => Promise<any>;
63
+ export declare const fetchFromApi: (apiUrl: string, body: ContentApiBaseBody, headers?: {}, method?: string) => Promise<any>;
64
64
  /** Guillotine-specialized fetch, using the generic fetch above */
65
- export declare const fetchGuillotine: (contentApiUrl: string, body: ContentApiBaseBody, xpContentPath: string) => Promise<GuillotineResult>;
65
+ export declare const fetchGuillotine: (contentApiUrl: string, body: ContentApiBaseBody, xpContentPath: string, headers?: {}) => Promise<GuillotineResult>;
66
66
  /**
67
67
  * Configures, builds and returns a general fetchContent function.
68
68
  * @param adapterConstants Object containing attributes imported from enonic-connecion-config.js: constants and function concerned with connection to the XP backend. Easiest: caller imports enonic-connection-config and just passes that entire object here as adapterConstants.
@@ -8,14 +8,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { getMetaQuery, pageFragmentQuery } from './getMetaData';
11
- import adapterConstants, { APP_NAME, APP_NAME_DASHED, FRAGMENT_CONTENTTYPE_NAME, FRAGMENT_DEFAULT_REGION_NAME, getContentApiUrl, getXpBaseUrl, IS_DEV_MODE, PAGE_TEMPLATE_CONTENTTYPE_NAME, PAGE_TEMPLATE_FOLDER, RENDER_MODE, sanitizeGraphqlName, SITE_KEY, XP_COMPONENT_TYPE, XP_REQUEST_TYPE, } from '../utils';
11
+ import adapterConstants, { APP_NAME, APP_NAME_DASHED, FRAGMENT_CONTENTTYPE_NAME, FRAGMENT_DEFAULT_REGION_NAME, getContentApiUrl, getXpBaseUrl, IS_DEV_MODE, JSESSIONID_HEADER, PAGE_TEMPLATE_CONTENTTYPE_NAME, PAGE_TEMPLATE_FOLDER, RENDER_MODE, sanitizeGraphqlName, SITE_KEY, XP_COMPONENT_TYPE, XP_REQUEST_TYPE, } from '../utils';
12
12
  import { ComponentRegistry } from '../ComponentRegistry';
13
13
  const NO_PROPS_PROCESSOR = (props) => __awaiter(void 0, void 0, void 0, function* () { var _a; return (_a = yield props) !== null && _a !== void 0 ? _a : {}; });
14
14
  const ALIAS_PREFIX = 'request';
15
15
  const GUILLOTINE_QUERY_REGEXP = /^\s*query\s*(?:\((.*)*\))?\s*{\s*guillotine\s*{((?:.|\s)+)}\s*}\s*$/;
16
16
  const GRAPHQL_FRAGMENTS_REGEXP = /fragment\s+.+\s+on\s+.+\s*{[\s\w{}().,:"'`]+}/;
17
17
  /** Generic fetch */
18
- export const fetchFromApi = (apiUrl, body, method = 'POST') => __awaiter(void 0, void 0, void 0, function* () {
18
+ export const fetchFromApi = (apiUrl, body, headers, method = 'POST') => __awaiter(void 0, void 0, void 0, function* () {
19
19
  const options = {
20
20
  method,
21
21
  headers: {
@@ -25,6 +25,9 @@ export const fetchFromApi = (apiUrl, body, method = 'POST') => __awaiter(void 0,
25
25
  },
26
26
  body: JSON.stringify(body),
27
27
  };
28
+ if (headers) {
29
+ Object.assign(options.headers, headers);
30
+ }
28
31
  let res;
29
32
  try {
30
33
  res = yield fetch(apiUrl, options);
@@ -61,7 +64,7 @@ export const fetchFromApi = (apiUrl, body, method = 'POST') => __awaiter(void 0,
61
64
  return json;
62
65
  });
63
66
  /** Guillotine-specialized fetch, using the generic fetch above */
64
- export const fetchGuillotine = (contentApiUrl, body, xpContentPath) => __awaiter(void 0, void 0, void 0, function* () {
67
+ export const fetchGuillotine = (contentApiUrl, body, xpContentPath, headers) => __awaiter(void 0, void 0, void 0, function* () {
65
68
  if (typeof body.query !== 'string' || !body.query.trim()) {
66
69
  return {
67
70
  error: {
@@ -70,7 +73,7 @@ export const fetchGuillotine = (contentApiUrl, body, xpContentPath) => __awaiter
70
73
  },
71
74
  };
72
75
  }
73
- const result = yield fetchFromApi(contentApiUrl, body)
76
+ const result = yield fetchFromApi(contentApiUrl, body, headers)
74
77
  .then(json => {
75
78
  let errors = (json || {}).errors;
76
79
  if (errors) {
@@ -104,7 +107,7 @@ export const fetchGuillotine = (contentApiUrl, body, xpContentPath) => __awaiter
104
107
  return result;
105
108
  });
106
109
  // /////////////////////////////////////////////////////////////////////////////// Specific fetch wrappers:
107
- const fetchMetaData = (contentApiUrl, xpContentPath) => __awaiter(void 0, void 0, void 0, function* () {
110
+ const fetchMetaData = (contentApiUrl, xpContentPath, headers) => __awaiter(void 0, void 0, void 0, function* () {
108
111
  var _b;
109
112
  const body = {
110
113
  query: getMetaQuery(pageFragmentQuery()),
@@ -112,7 +115,7 @@ const fetchMetaData = (contentApiUrl, xpContentPath) => __awaiter(void 0, void 0
112
115
  path: xpContentPath,
113
116
  },
114
117
  };
115
- const metaResult = yield fetchGuillotine(contentApiUrl, body, xpContentPath);
118
+ const metaResult = yield fetchGuillotine(contentApiUrl, body, xpContentPath, headers);
116
119
  if (metaResult.error) {
117
120
  return metaResult;
118
121
  }
@@ -122,12 +125,12 @@ const fetchMetaData = (contentApiUrl, xpContentPath) => __awaiter(void 0, void 0
122
125
  };
123
126
  }
124
127
  });
125
- const fetchContentData = (contentApiUrl, xpContentPath, query, variables) => __awaiter(void 0, void 0, void 0, function* () {
128
+ const fetchContentData = (contentApiUrl, xpContentPath, query, variables, headers) => __awaiter(void 0, void 0, void 0, function* () {
126
129
  const body = { query };
127
130
  if (variables && Object.keys(variables).length > 0) {
128
131
  body.variables = variables;
129
132
  }
130
- const contentResults = yield fetchGuillotine(contentApiUrl, body, xpContentPath);
133
+ const contentResults = yield fetchGuillotine(contentApiUrl, body, xpContentPath, headers);
131
134
  if (contentResults.error) {
132
135
  return contentResults;
133
136
  }
@@ -505,7 +508,14 @@ function errorResponse(code = '500', message = 'Unknown error', requestType, ren
505
508
  export const buildContentFetcher = (config) => {
506
509
  const { APP_NAME, APP_NAME_DASHED, getXPRequestType, getRenderMode, getSingleComponentPath, componentRegistry, } = config;
507
510
  return (contentPathOrArray, context) => __awaiter(void 0, void 0, void 0, function* () {
508
- var _a, _b;
511
+ var _a, _b, _c;
512
+ let headers;
513
+ const jsessionid = (_a = context === null || context === void 0 ? void 0 : context.req) === null || _a === void 0 ? void 0 : _a.headers[JSESSIONID_HEADER];
514
+ if (jsessionid) {
515
+ headers = {
516
+ 'Cookie': `${JSESSIONID_HEADER}=${jsessionid}`,
517
+ };
518
+ }
509
519
  const xpBaseUrl = getXpBaseUrl(context);
510
520
  const contentApiUrl = getContentApiUrl(context);
511
521
  const requestType = getXPRequestType(context);
@@ -518,7 +528,7 @@ export const buildContentFetcher = (config) => {
518
528
  requestedComponentPath = getSingleComponentPath(context);
519
529
  }
520
530
  // ///////////// FIRST GUILLOTINE CALL FOR METADATA /////////////////
521
- const metaResult = yield fetchMetaData(contentApiUrl, '${site}/' + siteRelativeContentPath);
531
+ const metaResult = yield fetchMetaData(contentApiUrl, '${site}/' + siteRelativeContentPath, headers);
522
532
  // ///////////////////////////////////////////////////////////////////////
523
533
  const { type, components, _path } = metaResult.meta || {};
524
534
  contentPath = _path || '';
@@ -545,14 +555,14 @@ export const buildContentFetcher = (config) => {
545
555
  if (pageCmp) {
546
556
  processComponentConfig(APP_NAME, APP_NAME_DASHED, pageCmp);
547
557
  }
548
- const contentQueryAndVars = getQueryAndVariables(type, contentPath, contentTypeDef === null || contentTypeDef === void 0 ? void 0 : contentTypeDef.query, context, (_a = pageCmp === null || pageCmp === void 0 ? void 0 : pageCmp.page) === null || _a === void 0 ? void 0 : _a.config);
558
+ const contentQueryAndVars = getQueryAndVariables(type, contentPath, contentTypeDef === null || contentTypeDef === void 0 ? void 0 : contentTypeDef.query, context, (_b = pageCmp === null || pageCmp === void 0 ? void 0 : pageCmp.page) === null || _b === void 0 ? void 0 : _b.config);
549
559
  if (contentQueryAndVars) {
550
560
  allDescriptors.push({
551
561
  type: contentTypeDef,
552
562
  queryAndVariables: contentQueryAndVars,
553
563
  });
554
564
  }
555
- const commonQueryAndVars = getQueryAndVariables(type, contentPath, componentRegistry.getCommonQuery(), context, (_b = pageCmp === null || pageCmp === void 0 ? void 0 : pageCmp.page) === null || _b === void 0 ? void 0 : _b.config);
565
+ const commonQueryAndVars = getQueryAndVariables(type, contentPath, componentRegistry.getCommonQuery(), context, (_c = pageCmp === null || pageCmp === void 0 ? void 0 : pageCmp.page) === null || _c === void 0 ? void 0 : _c.config);
556
566
  if (commonQueryAndVars) {
557
567
  allDescriptors.push({
558
568
  type: contentTypeDef,
@@ -574,7 +584,7 @@ export const buildContentFetcher = (config) => {
574
584
  return errorResponse('400', `Missing or empty query override for content type ${type}`, requestType, renderMode, contentApiUrl, xpBaseUrl, contentPath);
575
585
  }
576
586
  // /////////////// SECOND GUILLOTINE CALL FOR DATA //////////////////////
577
- const contentResults = yield fetchContentData(contentApiUrl, contentPath, query, variables);
587
+ const contentResults = yield fetchContentData(contentApiUrl, contentPath, query, variables, headers);
578
588
  // ///////////////////////////////////////////////////////////////////////////
579
589
  // Apply processors to every component
580
590
  const datas = yield applyProcessors(allDescriptors, contentResults, context);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enonic/nextjs-adapter",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "index.js",
6
6
  "publishConfig": {
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "html-react-parser": "^3.0.4",
17
- "next": "^13.0.3",
17
+ "next": "^13.0.4",
18
18
  "react": "^18.2.0",
19
19
  "react-dom": "^18.2.0",
20
20
  "unescape": "^1.0.1"
@@ -23,11 +23,11 @@
23
23
  "@enonic/eslint-config": "^0.1.0",
24
24
  "@types/node": "^18.11.9",
25
25
  "@types/react": "^18.0.25",
26
- "@types/react-dom": "^18.0.8",
27
- "@typescript-eslint/eslint-plugin": "^5.42.1",
28
- "@typescript-eslint/parser": "^5.42.1",
29
- "eslint": "^8.27.0",
30
- "eslint-plugin-react": "^7.31.10",
31
- "typescript": "^4.8.4"
26
+ "@types/react-dom": "^18.0.9",
27
+ "@typescript-eslint/eslint-plugin": "^5.43.0",
28
+ "@typescript-eslint/parser": "^5.44.0",
29
+ "eslint": "^8.28.0",
30
+ "eslint-plugin-react": "^7.31.11",
31
+ "typescript": "^4.9.3"
32
32
  }
33
33
  }
package/utils.d.ts CHANGED
@@ -12,6 +12,7 @@ export declare const FROM_XP_PARAM = "__fromxp__";
12
12
  export declare const XP_BASE_URL_HEADER = "xpbaseurl";
13
13
  export declare const COMPONENT_SUBPATH_HEADER = "xp-component-path";
14
14
  export declare const RENDER_MODE_HEADER = "content-studio-mode";
15
+ export declare const JSESSIONID_HEADER = "jsessionid";
15
16
  export declare const PORTAL_COMPONENT_ATTRIBUTE = "data-portal-component-type";
16
17
  export declare const PORTAL_REGION_ATTRIBUTE = "data-portal-region";
17
18
  export declare const FRAGMENT_CONTENTTYPE_NAME = "portal:fragment";
package/utils.js CHANGED
@@ -16,6 +16,7 @@ export const FROM_XP_PARAM = '__fromxp__';
16
16
  export const XP_BASE_URL_HEADER = 'xpbaseurl';
17
17
  export const COMPONENT_SUBPATH_HEADER = 'xp-component-path';
18
18
  export const RENDER_MODE_HEADER = 'content-studio-mode';
19
+ export const JSESSIONID_HEADER = 'jsessionid';
19
20
  export const PORTAL_COMPONENT_ATTRIBUTE = 'data-portal-component-type';
20
21
  export const PORTAL_REGION_ATTRIBUTE = 'data-portal-region';
21
22
  export const FRAGMENT_CONTENTTYPE_NAME = 'portal:fragment';
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { MetaData, PageComponent } from '../guillotine/getMetaData';
3
- export declare type BaseComponentProps = {
3
+ export type BaseComponentProps = {
4
4
  component: PageComponent;
5
5
  meta: MetaData;
6
6
  common?: any;
@@ -1,15 +1,16 @@
1
1
  /// <reference types="react" />
2
2
  import { MetaData, RichTextData } from '../guillotine/getMetaData';
3
3
  import { DOMNode } from 'html-react-parser';
4
- export declare type ReplacerResult = JSX.Element | object | void | undefined | null | false;
5
- export declare type Replacer = (domNode: DOMNode, data: RichTextData, meta: MetaData, renderMacroInEditMode: boolean) => ReplacerResult;
6
- declare type Props = {
4
+ export type ReplacerResult = JSX.Element | object | void | undefined | null | false;
5
+ export type Replacer = (domNode: DOMNode, data: RichTextData, meta: MetaData, renderMacroInEditMode: boolean) => ReplacerResult;
6
+ type Props = {
7
7
  data: RichTextData;
8
8
  meta: MetaData;
9
+ className?: string;
9
10
  tag?: string;
10
11
  renderMacroInEditMode?: boolean;
11
12
  customReplacer?: Replacer;
12
13
  };
13
14
  export declare function createReplacer(allData: RichTextData, meta: MetaData, renderMacroInEditMode?: boolean, customReplacer?: Replacer): (domNode: DOMNode) => ReplacerResult;
14
- declare const RichTextView: ({ tag, data, meta, renderMacroInEditMode, customReplacer }: Props) => JSX.Element;
15
+ declare const RichTextView: ({ className, tag, data, meta, renderMacroInEditMode, customReplacer }: Props) => JSX.Element;
15
16
  export default RichTextView;
@@ -46,9 +46,9 @@ export function createReplacer(allData, meta, renderMacroInEditMode = true, cust
46
46
  return el;
47
47
  };
48
48
  }
49
- const RichTextView = ({ tag, data, meta, renderMacroInEditMode, customReplacer }) => {
49
+ const RichTextView = ({ className, tag, data, meta, renderMacroInEditMode, customReplacer }) => {
50
50
  const CustomTag = tag || 'section';
51
- return <CustomTag>
51
+ return <CustomTag className={className}>
52
52
  {data.processedHtml ? HTMLReactParser(data.processedHtml, { replace: createReplacer(data, meta, renderMacroInEditMode, customReplacer) }) : ''}
53
53
  </CustomTag>;
54
54
  };
package/views/Text.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { MetaData, TextData } from '../guillotine/getMetaData';
3
- declare type Props = {
3
+ type Props = {
4
4
  meta: MetaData;
5
5
  component: TextData;
6
6
  path: string;