@enonic/nextjs-adapter 0.12.0 → 1.0.0-RC1

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/UrlProcessor.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { commonChars, RENDER_MODE, SITE_KEY } from './utils';
2
+ import { useRouter } from 'next/router';
2
3
  export class UrlProcessor {
3
4
  static process(url, meta) {
4
5
  let result;
@@ -9,7 +10,17 @@ export class UrlProcessor {
9
10
  else {
10
11
  const apiUrl = this.getApiUrl(meta);
11
12
  const strippedUrl = this.stripApiUrl(url, apiUrl);
12
- result = ((meta === null || meta === void 0 ? void 0 : meta.baseUrl) || '') + strippedUrl;
13
+ let basePath;
14
+ // only add basePath in next
15
+ if (meta.renderMode === RENDER_MODE.NEXT) {
16
+ try {
17
+ basePath = useRouter().basePath;
18
+ }
19
+ catch (e) {
20
+ console.error('Error getting basePath from nextjs router', e);
21
+ }
22
+ }
23
+ result = (basePath && basePath !== '/' ? basePath : '') + ((meta === null || meta === void 0 ? void 0 : meta.baseUrl) || '') + strippedUrl;
13
24
  }
14
25
  return result;
15
26
  }
@@ -24,6 +35,20 @@ export class UrlProcessor {
24
35
  var _a;
25
36
  return ((_a = linkData.find(data => data.ref === ref)) === null || _a === void 0 ? void 0 : _a.image) !== null;
26
37
  }
38
+ static processSrcSet(srcset, meta) {
39
+ return srcset.split(/, */g).map(src => {
40
+ const srcParts = src.trim().split(' ');
41
+ switch (srcParts.length) {
42
+ case 1:
43
+ return this.process(src, meta);
44
+ case 2:
45
+ return this.process(srcParts[0], meta) + ' ' + srcParts[1];
46
+ default:
47
+ console.warn('Can not process image srcset: ' + src);
48
+ return src;
49
+ }
50
+ }).join(', ');
51
+ }
27
52
  static stripApiUrl(url, apiUrl) {
28
53
  // normalise localhost-127.0.0.1 if present in urls
29
54
  const normalUrl = url.replace(this.localhostPattern, '127.0.0.1');
@@ -1,20 +1,10 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
3
  import { MetaData, PageComponent } from './getMetaData';
4
- import { RENDER_MODE, XP_REQUEST_TYPE } from '../utils';
5
- import { ComponentRegistry } from '../ComponentRegistry';
6
4
  import { ParsedUrlQuery } from 'node:querystring';
7
5
  import { type GetServerSidePropsContext } from 'next';
8
6
  import { IncomingMessage } from 'http';
9
7
  import { type NextApiRequestCookies } from 'next/dist/server/api-utils';
10
- export type AdapterConstants = {
11
- APP_NAME: string;
12
- APP_NAME_DASHED: string;
13
- SITE_KEY: string;
14
- getXPRequestType: (context?: Context) => XP_REQUEST_TYPE;
15
- getRenderMode: (context?: Context) => RENDER_MODE;
16
- getSingleComponentPath: (context?: Context) => string | undefined;
17
- };
18
8
  type Result = {
19
9
  error?: {
20
10
  code: string;
@@ -30,9 +20,6 @@ export type FetchContentResult = Result & {
30
20
  meta: MetaData;
31
21
  page: PageComponent | null;
32
22
  };
33
- type FetcherConfig<T extends AdapterConstants> = T & {
34
- componentRegistry: typeof ComponentRegistry;
35
- };
36
23
  export interface ServerSideParams extends ParsedUrlQuery {
37
24
  contentPath?: string[];
38
25
  mode?: string;
@@ -40,6 +27,7 @@ export interface ServerSideParams extends ParsedUrlQuery {
40
27
  export interface PreviewParams {
41
28
  contentPath: string[];
42
29
  headers: Record<string, string>;
30
+ params: Record<string, string>;
43
31
  }
44
32
  export type Context = GetServerSidePropsContext<ServerSideParams, PreviewParams>;
45
33
  export interface MinimalContext {
@@ -62,14 +50,7 @@ export type ContentApiBaseBody = {
62
50
  /** Generic fetch */
63
51
  export declare const fetchFromApi: (apiUrl: string, body: ContentApiBaseBody, headers?: {}, method?: string) => Promise<any>;
64
52
  /** Guillotine-specialized fetch, using the generic fetch above */
65
- export declare const fetchGuillotine: (contentApiUrl: string, body: ContentApiBaseBody, xpContentPath: string, headers?: {}) => Promise<GuillotineResult>;
66
- /**
67
- * Configures, builds and returns a general fetchContent function.
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.
69
- * @param componentRegistry ComponentRegistry object from ComponentRegistry.ts, holding user type mappings that are set in typesRegistration.ts file
70
- * @returns ContentFetcher
71
- */
72
- export declare const buildContentFetcher: <T extends AdapterConstants>(config: FetcherConfig<T>) => ContentFetcher;
53
+ export declare const fetchGuillotine: (contentApiUrl: string, body: ContentApiBaseBody, headers?: {}) => Promise<GuillotineResult>;
73
54
  /**
74
55
  * Default fetchContent function, built with params from imports.
75
56
  * It runs custom content-type-specific guillotine calls against an XP guillotine endpoint, returns content data, error and some meta data
@@ -8,7 +8,7 @@ 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, JSESSIONID_HEADER, 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, getJsessionHeaders, getRenderMode, getXpBaseUrl, IS_DEV_MODE, 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';
@@ -64,7 +64,8 @@ export const fetchFromApi = (apiUrl, body, headers, method = 'POST') => __awaite
64
64
  return json;
65
65
  });
66
66
  /** Guillotine-specialized fetch, using the generic fetch above */
67
- export const fetchGuillotine = (contentApiUrl, body, xpContentPath, headers) => __awaiter(void 0, void 0, void 0, function* () {
67
+ export const fetchGuillotine = (contentApiUrl, body, headers) => __awaiter(void 0, void 0, void 0, function* () {
68
+ var _b;
68
69
  if (typeof body.query !== 'string' || !body.query.trim()) {
69
70
  return {
70
71
  error: {
@@ -73,6 +74,8 @@ export const fetchGuillotine = (contentApiUrl, body, xpContentPath, headers) =>
73
74
  },
74
75
  };
75
76
  }
77
+ const path = (_b = body.variables) === null || _b === void 0 ? void 0 : _b.path;
78
+ const pathMessage = path ? `(path = ${JSON.stringify(path)})` : '';
76
79
  const result = yield fetchFromApi(contentApiUrl, body, headers)
77
80
  .then(json => {
78
81
  let errors = (json || {}).errors;
@@ -80,7 +83,7 @@ export const fetchGuillotine = (contentApiUrl, body, xpContentPath, headers) =>
80
83
  if (!Array.isArray(errors)) {
81
84
  errors = [errors];
82
85
  }
83
- console.warn(`${errors.length} error(s) when trying to fetch data (path = ${JSON.stringify(xpContentPath)}):`);
86
+ console.warn(`${errors.length} error(s) when trying to fetch data ${pathMessage}:`);
84
87
  errors.forEach(error => {
85
88
  console.error(error);
86
89
  });
@@ -96,7 +99,7 @@ export const fetchGuillotine = (contentApiUrl, body, xpContentPath, headers) =>
96
99
  return json.data;
97
100
  })
98
101
  .catch((err) => {
99
- console.warn(`Client-side error when trying to fetch data (path = ${JSON.stringify(xpContentPath)})`, err);
102
+ console.warn(`Client-side error when trying to fetch data ${pathMessage}`, err);
100
103
  try {
101
104
  return { error: JSON.parse(err.message) };
102
105
  }
@@ -108,20 +111,20 @@ export const fetchGuillotine = (contentApiUrl, body, xpContentPath, headers) =>
108
111
  });
109
112
  // /////////////////////////////////////////////////////////////////////////////// Specific fetch wrappers:
110
113
  const fetchMetaData = (contentApiUrl, xpContentPath, headers) => __awaiter(void 0, void 0, void 0, function* () {
111
- var _b;
114
+ var _c;
112
115
  const body = {
113
116
  query: getMetaQuery(pageFragmentQuery()),
114
117
  variables: {
115
118
  path: xpContentPath,
116
119
  },
117
120
  };
118
- const metaResult = yield fetchGuillotine(contentApiUrl, body, xpContentPath, headers);
121
+ const metaResult = yield fetchGuillotine(contentApiUrl, body, headers);
119
122
  if (metaResult.error) {
120
123
  return metaResult;
121
124
  }
122
125
  else {
123
126
  return {
124
- meta: (_b = metaResult === null || metaResult === void 0 ? void 0 : metaResult.guillotine) === null || _b === void 0 ? void 0 : _b.get,
127
+ meta: (_c = metaResult === null || metaResult === void 0 ? void 0 : metaResult.guillotine) === null || _c === void 0 ? void 0 : _c.get,
125
128
  };
126
129
  }
127
130
  });
@@ -130,7 +133,7 @@ const fetchContentData = (contentApiUrl, xpContentPath, query, variables, header
130
133
  if (variables && Object.keys(variables).length > 0) {
131
134
  body.variables = variables;
132
135
  }
133
- const contentResults = yield fetchGuillotine(contentApiUrl, body, xpContentPath, headers);
136
+ const contentResults = yield fetchGuillotine(contentApiUrl, body, headers);
134
137
  if (contentResults.error) {
135
138
  return contentResults;
136
139
  }
@@ -230,27 +233,40 @@ function prefixLayoutPath(contentType, path) {
230
233
  }
231
234
  }
232
235
  function buildPage(contentType, comps = []) {
233
- let page = {
236
+ const page = {
234
237
  type: XP_COMPONENT_TYPE.PAGE,
235
238
  path: '/',
236
239
  };
237
- const tree = {};
238
- if (contentType === FRAGMENT_CONTENTTYPE_NAME) {
239
- page.regions = tree;
240
+ return buildComponentTree(comps, page, contentType);
241
+ }
242
+ function buildComponentTree(comps, rootComp, contentType) {
243
+ const rootTree = {};
244
+ const isFragmentType = contentType === FRAGMENT_CONTENTTYPE_NAME;
245
+ if (isFragmentType) {
246
+ rootComp.regions = rootTree;
240
247
  }
241
248
  comps.forEach(cmp => {
242
249
  var _a;
243
250
  const cmpPath = parseComponentPath(contentType, cmp.path);
244
- let region;
245
- if (cmp.path === '/' && cmp.type === XP_COMPONENT_TYPE.PAGE) {
246
- // add page values to page object
247
- page = Object.assign(page, cmp);
248
- page.page.regions = tree;
249
- return;
251
+ if (cmp.path === '/') {
252
+ if (cmp.type === XP_COMPONENT_TYPE.PAGE && rootComp.type === XP_COMPONENT_TYPE.PAGE) {
253
+ // add page values to page object
254
+ rootComp = Object.assign(rootComp, cmp);
255
+ rootComp.page.regions = rootTree;
256
+ return;
257
+ }
258
+ else if (cmp.type === XP_COMPONENT_TYPE.LAYOUT && rootComp.type === XP_COMPONENT_TYPE.FRAGMENT) {
259
+ // when rendering fragment as part of the page with layout at root path
260
+ // remove other children from list as they will be included in layout
261
+ rootComp.fragment.fragment.components = [cmp];
262
+ cmp.regions = rootTree;
263
+ }
250
264
  }
251
- else {
252
- region = getParentRegion(tree, contentType, cmpPath, comps, true);
265
+ if (cmp.type === XP_COMPONENT_TYPE.FRAGMENT) {
266
+ // build component subtree for fragment
267
+ cmp = buildComponentTree(cmp.fragment.fragment.components, cmp, contentType);
253
268
  }
269
+ const region = getParentRegion(rootTree, contentType, cmpPath, comps, true);
254
270
  if (region) {
255
271
  // getting the index of component from string like '/main/0/left/11'
256
272
  const cmpIndex = (_a = cmpPath[cmpPath.length - 1]) === null || _a === void 0 ? void 0 : _a.index;
@@ -262,7 +278,7 @@ function buildPage(contentType, comps = []) {
262
278
  }
263
279
  }
264
280
  });
265
- return page;
281
+ return rootComp;
266
282
  }
267
283
  function combineMultipleQueries(queriesWithVars) {
268
284
  const queries = [];
@@ -342,12 +358,17 @@ function applyProcessors(componentDescriptors, contentResults, context) {
342
358
  // if there is a query then there must be a result for it
343
359
  data = contentResults.contents[dataCounter++];
344
360
  }
345
- return yield propsProcessor(data, context);
361
+ const config = getComponentConfig(desc.component);
362
+ return yield propsProcessor(data, context, config);
346
363
  }));
347
364
  return Promise.allSettled(processorPromises);
348
365
  });
349
366
  }
350
- function collectComponentDescriptors(components, componentRegistry, requestedComponentPath, xpContentPath, context) {
367
+ function getComponentConfig(cmp) {
368
+ const cmpData = cmp && cmp[cmp.type];
369
+ return cmpData && 'config' in cmpData ? cmpData.config : undefined;
370
+ }
371
+ function collectComponentDescriptors(components, componentRegistry, xpContentPath, context) {
351
372
  const descriptors = [];
352
373
  for (const cmp of (components || [])) {
353
374
  processComponentConfig(APP_NAME, APP_NAME_DASHED, cmp);
@@ -357,8 +378,7 @@ function collectComponentDescriptors(components, componentRegistry, requestedCom
357
378
  const cmpDef = ComponentRegistry.getByComponent(cmp);
358
379
  if (cmpDef) {
359
380
  // const partPath = `${xpContentPath}/_component${cmp.path}`;
360
- const cmpData = cmp[cmp.type];
361
- const config = cmpData && 'config' in cmpData ? cmpData.config : undefined;
381
+ const config = getComponentConfig(cmp);
362
382
  const queryAndVariables = getQueryAndVariables(cmp.type, xpContentPath, cmpDef.query, context, config);
363
383
  if (queryAndVariables) {
364
384
  descriptors.push({
@@ -371,7 +391,7 @@ function collectComponentDescriptors(components, componentRegistry, requestedCom
371
391
  }
372
392
  else {
373
393
  // look for parts inside fragments
374
- const fragPartDescs = collectComponentDescriptors(cmp.fragment.fragment.components, componentRegistry, requestedComponentPath, xpContentPath, context);
394
+ const fragPartDescs = collectComponentDescriptors(cmp.fragment.fragment.components, componentRegistry, xpContentPath, context);
375
395
  if (fragPartDescs.length) {
376
396
  descriptors.push(...fragPartDescs);
377
397
  }
@@ -427,7 +447,7 @@ function getQueryAndVariables(type, path, selectedQuery, context, config) {
427
447
  throw Error(`Query for content type ${type} should be a string or function, not: ${typeof query}`);
428
448
  }
429
449
  if (typeof query === 'function') {
430
- query = query(config);
450
+ query = query(path, context, config);
431
451
  }
432
452
  if (query) {
433
453
  return {
@@ -436,11 +456,15 @@ function getQueryAndVariables(type, path, selectedQuery, context, config) {
436
456
  };
437
457
  }
438
458
  }
439
- function createPageData(contentType, components) {
459
+ function createPageData(contentType, components, componentPath) {
440
460
  let page;
441
- if (components) {
461
+ if (components && !componentPath) {
442
462
  page = buildPage(contentType, components);
443
463
  }
464
+ else {
465
+ // Don't build page for single component
466
+ page = null;
467
+ }
444
468
  return page;
445
469
  }
446
470
  function createMetaData(contentType, contentPath, requestType, renderMode, apiUrl, baseUrl, requestedComponentPath, pageCmp, components = []) {
@@ -466,10 +490,13 @@ function createMetaData(contentType, contentPath, requestType, renderMode, apiUr
466
490
  if ((typeDef === null || typeDef === void 0 ? void 0 : typeDef.view) && !typeDef.catchAll) {
467
491
  meta.canRender = true;
468
492
  }
493
+ else if (requestType === XP_REQUEST_TYPE.COMPONENT) {
494
+ // always render a single component (show missing if not implemented)
495
+ meta.canRender = true;
496
+ }
469
497
  else if (pageDesc) {
470
- // always render a page if there is a descriptor (show missing in case it's not implemented)
498
+ // always render a page if there is a descriptor (show missing if not implemented)
471
499
  meta.canRender = true;
472
- meta.catchAll = false; // catchAll only refers to content type catch-all
473
500
  }
474
501
  else if (typeDef === null || typeDef === void 0 ? void 0 : typeDef.view) {
475
502
  meta.canRender = true;
@@ -498,40 +525,76 @@ function errorResponse(code = '500', message = 'Unknown error', requestType, ren
498
525
  },
499
526
  };
500
527
  }
528
+ function restrictComponentsToPath(contentType, components, componentPath) {
529
+ if (!componentPath || !(components === null || components === void 0 ? void 0 : components.length)) {
530
+ return components || [];
531
+ }
532
+ // filter components to the requested one only
533
+ const component = components.find(cmp => {
534
+ return cmp.path === componentPath;
535
+ });
536
+ if (!component) {
537
+ return [];
538
+ }
539
+ let result = [component];
540
+ if (component.type !== XP_COMPONENT_TYPE.LAYOUT) {
541
+ // remember to include all parent layouts too !
542
+ const cmpPath = parseComponentPath(contentType, component.path);
543
+ for (let i = cmpPath.length - 2; i >= 0; i--) {
544
+ const parentPath = cmpPath[i];
545
+ const parentCmp = components.find(cmp => cmp.path === `/${parentPath.region}/${parentPath.index}`);
546
+ if (parentCmp) {
547
+ result.unshift(parentCmp);
548
+ }
549
+ }
550
+ }
551
+ else {
552
+ // It's a layout, include child components
553
+ const childCmps = components.filter(cmp => cmp.path !== component.path && cmp.path.startsWith(component.path));
554
+ if (childCmps.length) {
555
+ result = result.concat(childCmps);
556
+ }
557
+ }
558
+ return result;
559
+ }
560
+ const COMPONENT_PATH_KEY = /\/?_\/component/; // first slash is optional for root components
561
+ const getContentAndComponentPaths = (requestPath, context) => {
562
+ let contentPath, componentPath;
563
+ if (COMPONENT_PATH_KEY.test(requestPath)) {
564
+ [contentPath, componentPath] = requestPath.split(COMPONENT_PATH_KEY);
565
+ }
566
+ else {
567
+ contentPath = requestPath;
568
+ }
569
+ return [contentPath, componentPath];
570
+ };
501
571
  // ///////////////////////////// ENTRY 1 - THE BUILDER:
502
572
  /**
503
573
  * Configures, builds and returns a general fetchContent function.
504
- * @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.
505
- * @param componentRegistry ComponentRegistry object from ComponentRegistry.ts, holding user type mappings that are set in typesRegistration.ts file
574
+ * @param config object containing ComponentRegistry as well as constants imported from enonic-connecion-config.js
506
575
  * @returns ContentFetcher
507
576
  */
508
- export const buildContentFetcher = (config) => {
509
- const { APP_NAME, APP_NAME_DASHED, getXPRequestType, getRenderMode, getSingleComponentPath, componentRegistry, } = config;
577
+ const buildContentFetcher = (config) => {
578
+ const { APP_NAME, APP_NAME_DASHED, componentRegistry, } = config;
510
579
  return (contentPathOrArray, context) => __awaiter(void 0, void 0, void 0, function* () {
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
- }
580
+ var _a, _b;
581
+ const headers = getJsessionHeaders(context);
519
582
  const xpBaseUrl = getXpBaseUrl(context);
520
583
  const contentApiUrl = getContentApiUrl(context);
521
- const requestType = getXPRequestType(context);
522
584
  const renderMode = getRenderMode(context);
523
- let contentPath;
585
+ let requestType = XP_REQUEST_TYPE.TYPE;
524
586
  try {
525
- const siteRelativeContentPath = getCleanContentPathArrayOrThrow400(contentPathOrArray);
526
- let requestedComponentPath;
527
- if (requestType === XP_REQUEST_TYPE.COMPONENT) {
528
- requestedComponentPath = getSingleComponentPath(context);
587
+ const requestContentPath = getCleanContentPathArrayOrThrow400(contentPathOrArray);
588
+ const [siteRelativeContentPath, componentPath] = getContentAndComponentPaths(requestContentPath, context);
589
+ if (componentPath) {
590
+ // set component request type because url contains component path
591
+ requestType = XP_REQUEST_TYPE.COMPONENT;
529
592
  }
530
593
  // ///////////// FIRST GUILLOTINE CALL FOR METADATA /////////////////
531
594
  const metaResult = yield fetchMetaData(contentApiUrl, '${site}/' + siteRelativeContentPath, headers);
532
595
  // ///////////////////////////////////////////////////////////////////////
533
- const { type, components, _path } = metaResult.meta || {};
534
- contentPath = _path || '';
596
+ const { _path, type } = metaResult.meta || {};
597
+ const contentPath = _path || siteRelativeContentPath;
535
598
  if (metaResult.error) {
536
599
  console.error(metaResult.error);
537
600
  return errorResponse(metaResult.error.code, metaResult.error.message, requestType, renderMode, contentApiUrl, xpBaseUrl, contentPath);
@@ -548,6 +611,14 @@ export const buildContentFetcher = (config) => {
548
611
  type === PAGE_TEMPLATE_FOLDER)) {
549
612
  return errorResponse('404', `Content type [${type}] is not accessible in ${renderMode} mode`, requestType, renderMode, contentApiUrl, xpBaseUrl, contentPath);
550
613
  }
614
+ const components = restrictComponentsToPath(type, metaResult.meta.components, componentPath);
615
+ if (componentPath && !components.length) {
616
+ // component was not found
617
+ return errorResponse('404', `Component ${componentPath} was not found`, requestType, renderMode, contentApiUrl, xpBaseUrl, contentPath);
618
+ }
619
+ if (requestType !== XP_REQUEST_TYPE.COMPONENT && components.length > 0) {
620
+ requestType = XP_REQUEST_TYPE.PAGE;
621
+ }
551
622
  // ////////////////////////////////////////////////// Content type established. Proceed to data call:
552
623
  const allDescriptors = [];
553
624
  // Add the content type query at all cases
@@ -556,14 +627,14 @@ export const buildContentFetcher = (config) => {
556
627
  if (pageCmp) {
557
628
  processComponentConfig(APP_NAME, APP_NAME_DASHED, pageCmp);
558
629
  }
559
- 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);
630
+ 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);
560
631
  if (contentQueryAndVars) {
561
632
  allDescriptors.push({
562
633
  type: contentTypeDef,
563
634
  queryAndVariables: contentQueryAndVars,
564
635
  });
565
636
  }
566
- 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);
637
+ 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);
567
638
  if (commonQueryAndVars) {
568
639
  allDescriptors.push({
569
640
  type: contentTypeDef,
@@ -575,7 +646,7 @@ export const buildContentFetcher = (config) => {
575
646
  processComponentConfig(APP_NAME, APP_NAME_DASHED, cmp);
576
647
  }
577
648
  // Collect component queries if defined
578
- const componentDescriptors = collectComponentDescriptors(components, componentRegistry, requestedComponentPath, contentPath, context);
649
+ const componentDescriptors = collectComponentDescriptors(components, componentRegistry, contentPath, context);
579
650
  if (componentDescriptors.length) {
580
651
  allDescriptors.push(...componentDescriptors);
581
652
  }
@@ -625,14 +696,13 @@ export const buildContentFetcher = (config) => {
625
696
  }
626
697
  }
627
698
  const page = createPageData(type, components);
628
- const meta = createMetaData(type, siteRelativeContentPath, requestType, renderMode, contentApiUrl, xpBaseUrl, requestedComponentPath, page, components);
699
+ const meta = createMetaData(type, siteRelativeContentPath, requestType, renderMode, contentApiUrl, xpBaseUrl, componentPath, page, components);
629
700
  return {
630
701
  data: contentData,
631
702
  common,
632
703
  meta,
633
- page: page || null,
704
+ page,
634
705
  };
635
- // /////////////////////////////////////////////////////////// Catch
636
706
  }
637
707
  catch (e) {
638
708
  console.error(e);
@@ -646,7 +716,7 @@ export const buildContentFetcher = (config) => {
646
716
  message: e.message,
647
717
  };
648
718
  }
649
- return errorResponse(error.code, error.message, requestType, renderMode, contentApiUrl, xpBaseUrl, contentPath);
719
+ return errorResponse(error.code, error.message, requestType, renderMode, contentApiUrl, xpBaseUrl, contentPathOrArray.toString());
650
720
  }
651
721
  });
652
722
  };
package/index.d.ts CHANGED
@@ -1,2 +1,5 @@
1
1
  export * from './utils';
2
2
  export * from './guillotine/fetchContent';
3
+ export * from './guillotine/getMetaData';
4
+ export * from './ComponentRegistry';
5
+ export * from './UrlProcessor';
package/index.js CHANGED
@@ -1,2 +1,5 @@
1
1
  export * from './utils';
2
2
  export * from './guillotine/fetchContent';
3
+ export * from './guillotine/getMetaData';
4
+ export * from './ComponentRegistry';
5
+ export * from './UrlProcessor';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enonic/nextjs-adapter",
3
- "version": "0.12.0",
3
+ "version": "1.0.0-RC1",
4
4
  "license": "Apache-2.0",
5
5
  "main": "index.js",
6
6
  "publishConfig": {
@@ -8,26 +8,27 @@
8
8
  },
9
9
  "scripts": {
10
10
  "copy": "npx --yes cpy-cli package.json README.md dist",
11
- "build": "tsc",
12
- "lint": "eslint --quiet .",
13
- "lint:fix": "eslint --fix ."
11
+ "build": "tsc --build src/tsconfig.json && tsc --build server/tsconfig.json",
12
+ "lint": "eslint --quiet server && eslint --quiet src",
13
+ "lint:fix": "eslint --fix server && eslint --fix src"
14
14
  },
15
15
  "dependencies": {
16
- "html-react-parser": "^3.0.4",
17
- "next": "^13.0.7",
16
+ "html-react-parser": "^3.0.11",
17
+ "lru-cache": "^7.17.0",
18
+ "next": "^13.2.3",
18
19
  "react": "^18.2.0",
19
20
  "react-dom": "^18.2.0",
20
21
  "unescape": "^1.0.1"
21
22
  },
22
23
  "devDependencies": {
23
- "@enonic/eslint-config": "^0.1.0",
24
- "@types/node": "^18.11.17",
25
- "@types/react": "^18.0.26",
26
- "@types/react-dom": "^18.0.9",
27
- "@typescript-eslint/eslint-plugin": "^5.46.1",
28
- "@typescript-eslint/parser": "^5.46.1",
29
- "eslint": "^8.30.0",
30
- "eslint-plugin-react": "^7.31.11",
31
- "typescript": "^4.9.4"
24
+ "@enonic/eslint-config": "^1.1.0",
25
+ "@types/node": "^18.14.6",
26
+ "@types/react": "^18.0.28",
27
+ "@types/react-dom": "^18.0.11",
28
+ "@typescript-eslint/eslint-plugin": "^5.54.0",
29
+ "@typescript-eslint/parser": "^5.54.0",
30
+ "eslint": "^8.35.0",
31
+ "eslint-plugin-react": "^7.32.2",
32
+ "typescript": "^4.9.5"
32
33
  }
33
34
  }