@enonic/nextjs-adapter 3.0.0-B3 → 3.0.0-B4

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 (163) hide show
  1. package/LICENSE +201 -0
  2. package/baseMappings.js.map +1 -1
  3. package/client.js.map +1 -1
  4. package/common/ComponentRegistry.js.map +1 -1
  5. package/common/UrlProcessor.js.map +1 -1
  6. package/common/constants.js.map +1 -1
  7. package/common/env.js.map +1 -1
  8. package/guillotine/applyProcessors.js.map +1 -1
  9. package/guillotine/buildComponentTree.js.map +1 -1
  10. package/guillotine/buildErrorResponse.js.map +1 -1
  11. package/guillotine/buildPage.js.map +1 -1
  12. package/guillotine/collectComponentDescriptors.js.map +1 -1
  13. package/guillotine/combineMultipleQueries.js.map +1 -1
  14. package/guillotine/createMetaData.js.map +1 -1
  15. package/guillotine/fetchContent.js.map +1 -1
  16. package/guillotine/fetchContentData.js.map +1 -1
  17. package/guillotine/fetchContentPathsForAllLocales.js.map +1 -1
  18. package/guillotine/fetchContentPathsForLocale.js.map +1 -1
  19. package/guillotine/fetchFromApi.js.map +1 -1
  20. package/guillotine/fetchGuillotine.js.map +1 -1
  21. package/guillotine/fetchMetaData.js.map +1 -1
  22. package/guillotine/getCleanContentPathArrayOrThrow400.js.map +1 -1
  23. package/guillotine/getComponentConfig.js.map +1 -1
  24. package/guillotine/getContentAndComponentPaths.js.map +1 -1
  25. package/guillotine/getMetaData.js.map +1 -1
  26. package/guillotine/getParentRegion.js.map +1 -1
  27. package/guillotine/getQueryAndVariables.js.map +1 -1
  28. package/guillotine/metadata/configQuery.js.map +1 -1
  29. package/guillotine/metadata/richTextQuery.js.map +1 -1
  30. package/guillotine/parseComponentPath.js.map +1 -1
  31. package/guillotine/prefixLayoutPath.js.map +1 -1
  32. package/guillotine/processComponentConfig.js.map +1 -1
  33. package/guillotine/restrictComponentsToPath.js.map +1 -1
  34. package/guillotine/validateData.js.map +1 -1
  35. package/guillotine/validateNotFound.js.map +1 -1
  36. package/guillotine/validateShortcut.js.map +1 -1
  37. package/i18n/LocaleContext.jsx.map +1 -1
  38. package/i18n/i18n.js.map +1 -1
  39. package/index.js.map +1 -1
  40. package/package.json +3 -4
  41. package/query/Shortcut.js.map +1 -1
  42. package/server.js +6 -0
  43. package/server.js.map +1 -1
  44. package/src/baseMappings.ts +53 -0
  45. package/src/client.ts +2 -0
  46. package/src/common/ComponentRegistry.ts +162 -0
  47. package/src/common/UrlProcessor.ts +142 -0
  48. package/src/common/constants.ts +85 -0
  49. package/src/common/env.ts +39 -0
  50. package/src/guillotine/applyProcessors.ts +38 -0
  51. package/src/guillotine/buildComponentTree.ts +63 -0
  52. package/src/guillotine/buildErrorResponse.ts +39 -0
  53. package/src/guillotine/buildPage.ts +15 -0
  54. package/src/guillotine/collectComponentDescriptors.ts +63 -0
  55. package/src/guillotine/combineMultipleQueries.ts +75 -0
  56. package/src/guillotine/createMetaData.ts +73 -0
  57. package/src/guillotine/fetchContent.ts +250 -0
  58. package/src/guillotine/fetchContentData.ts +33 -0
  59. package/src/guillotine/fetchContentPathsForAllLocales.ts +21 -0
  60. package/src/guillotine/fetchContentPathsForLocale.ts +42 -0
  61. package/src/guillotine/fetchFromApi.ts +69 -0
  62. package/src/guillotine/fetchGuillotine.ts +61 -0
  63. package/src/guillotine/fetchMetaData.ts +32 -0
  64. package/src/guillotine/getCleanContentPathArrayOrThrow400.ts +22 -0
  65. package/src/guillotine/getComponentConfig.ts +7 -0
  66. package/src/guillotine/getContentAndComponentPaths.ts +11 -0
  67. package/src/guillotine/getMetaData.ts +73 -0
  68. package/src/guillotine/getParentRegion.ts +59 -0
  69. package/src/guillotine/getQueryAndVariables.ts +52 -0
  70. package/src/guillotine/metadata/configQuery.ts +46 -0
  71. package/src/guillotine/metadata/richTextQuery.ts +34 -0
  72. package/src/guillotine/parseComponentPath.ts +29 -0
  73. package/src/guillotine/prefixLayoutPath.ts +16 -0
  74. package/src/guillotine/processComponentConfig.ts +38 -0
  75. package/src/guillotine/restrictComponentsToPath.ts +45 -0
  76. package/src/guillotine/validateData.ts +11 -0
  77. package/src/guillotine/validateNotFound.ts +20 -0
  78. package/src/guillotine/validateShortcut.ts +37 -0
  79. package/src/i18n/LocaleContext.tsx +54 -0
  80. package/src/i18n/i18n.ts +54 -0
  81. package/src/index.ts +42 -0
  82. package/src/query/Shortcut.ts +14 -0
  83. package/src/server.ts +5 -0
  84. package/src/types/component.ts +147 -0
  85. package/src/types/componentProps.ts +142 -0
  86. package/src/types/guillotine.ts +426 -0
  87. package/src/types/i18n.ts +8 -0
  88. package/src/types/index.ts +58 -0
  89. package/src/types/next.ts +7 -0
  90. package/src/types/util.ts +5 -0
  91. package/src/utils/addLineNumbers.ts +3 -0
  92. package/src/utils/buildGuillotineRequestHeaders.ts +32 -0
  93. package/src/utils/commonChars.ts +16 -0
  94. package/src/utils/fixDoubleSlashes.ts +3 -0
  95. package/src/utils/getContentApiUrl.ts +20 -0
  96. package/src/utils/getProjectLocaleConfig.ts +24 -0
  97. package/src/utils/getProjectLocaleConfigById.ts +21 -0
  98. package/src/utils/getProjectLocaleConfigByLocale.ts +19 -0
  99. package/src/utils/getProjectLocaleConfigs.ts +36 -0
  100. package/src/utils/getProjectLocales.ts +6 -0
  101. package/src/utils/getRenderMode.ts +14 -0
  102. package/src/utils/getRequestLocaleInfo.ts +29 -0
  103. package/src/utils/getXpBaseUrl.ts +12 -0
  104. package/src/utils/indent.ts +4 -0
  105. package/src/utils/sanitizeGraphqlName.ts +11 -0
  106. package/src/views/BaseComponent.tsx +153 -0
  107. package/src/views/BaseContent.tsx +47 -0
  108. package/src/views/BaseLayout.tsx +33 -0
  109. package/src/views/BaseMacro.tsx +94 -0
  110. package/src/views/BasePage.tsx +42 -0
  111. package/src/views/BasePart.tsx +34 -0
  112. package/src/views/Empty.tsx +5 -0
  113. package/src/views/Fragment.tsx +41 -0
  114. package/src/views/MainView.tsx +22 -0
  115. package/src/views/PropsView.tsx +38 -0
  116. package/src/views/Region.tsx +76 -0
  117. package/src/views/RichTextView.tsx +75 -0
  118. package/src/views/SingleComponent.tsx +19 -0
  119. package/src/views/StaticContent.tsx +39 -0
  120. package/src/views/Text.tsx +19 -0
  121. package/src/views/getClientHydratedHtml.tsx +12 -0
  122. package/src/views/macros/DefaultMacro.tsx +9 -0
  123. package/src/views/macros/DisableMacro.tsx +8 -0
  124. package/types/component.js.map +1 -1
  125. package/types/componentProps.js.map +1 -1
  126. package/types/guillotine.js.map +1 -1
  127. package/types/i18n.js.map +1 -1
  128. package/types/index.js.map +1 -1
  129. package/types/next.js.map +1 -1
  130. package/types/util.js.map +1 -1
  131. package/utils/addLineNumbers.js.map +1 -1
  132. package/utils/buildGuillotineRequestHeaders.js.map +1 -1
  133. package/utils/commonChars.js.map +1 -1
  134. package/utils/fixDoubleSlashes.js.map +1 -1
  135. package/utils/getContentApiUrl.js.map +1 -1
  136. package/utils/getProjectLocaleConfig.js.map +1 -1
  137. package/utils/getProjectLocaleConfigById.js.map +1 -1
  138. package/utils/getProjectLocaleConfigByLocale.js.map +1 -1
  139. package/utils/getProjectLocaleConfigs.js.map +1 -1
  140. package/utils/getProjectLocales.js.map +1 -1
  141. package/utils/getRenderMode.js.map +1 -1
  142. package/utils/getRequestLocaleInfo.js.map +1 -1
  143. package/utils/getXpBaseUrl.js.map +1 -1
  144. package/utils/indent.js.map +1 -1
  145. package/utils/sanitizeGraphqlName.js.map +1 -1
  146. package/views/BaseComponent.jsx.map +1 -1
  147. package/views/BaseContent.jsx.map +1 -1
  148. package/views/BaseLayout.jsx.map +1 -1
  149. package/views/BaseMacro.jsx.map +1 -1
  150. package/views/BasePage.jsx.map +1 -1
  151. package/views/BasePart.jsx.map +1 -1
  152. package/views/Empty.jsx.map +1 -1
  153. package/views/Fragment.jsx.map +1 -1
  154. package/views/MainView.jsx.map +1 -1
  155. package/views/PropsView.jsx.map +1 -1
  156. package/views/Region.jsx.map +1 -1
  157. package/views/RichTextView.jsx.map +1 -1
  158. package/views/SingleComponent.jsx.map +1 -1
  159. package/views/StaticContent.jsx.map +1 -1
  160. package/views/Text.jsx.map +1 -1
  161. package/views/getClientHydratedHtml.jsx.map +1 -1
  162. package/views/macros/DefaultMacro.jsx.map +1 -1
  163. package/views/macros/DisableMacro.jsx.map +1 -1
@@ -0,0 +1,54 @@
1
+ import type {Dict} from '../types';
2
+
3
+
4
+ export class I18n {
5
+ private static locale = '';
6
+ private static dictionary: Dict = {};
7
+
8
+ public static async setLocale(locale: string): Promise<Dict> {
9
+ this.locale = locale;
10
+ return loadPhrases(locale).then((phrases) => {
11
+ this.dictionary = phrases;
12
+ console.info(`Loaded server-side phrases for locale "${locale}"`);
13
+ return phrases;
14
+ });
15
+ }
16
+
17
+ public static localize(key: string, ...args: any[]): string {
18
+ return getPhrase(this.locale, this.dictionary, key, ...args);
19
+ }
20
+
21
+ public static getLocale() {
22
+ return this.locale;
23
+ }
24
+
25
+ public static getDictionary() {
26
+ return this.dictionary;
27
+ }
28
+ }
29
+
30
+ export const loadPhrases = async (locale: string): Promise<Dict> => {
31
+ return import(`@phrases/${locale}.json`)
32
+ .then((module) => module.default)
33
+ .catch((e) => {
34
+ console.error(`Failed to load phrases for locale "${locale}"`, e);
35
+ return {};
36
+ });
37
+ };
38
+
39
+ export const getPhrase = (locale: string, dict: Dict, key: string, ...args: any[]) => {
40
+ const template = dict[key];
41
+ if (!template) {
42
+ console.warn(`Missing localization phrase for locale "${locale}": <${key}>`);
43
+ return `<${key}>`;
44
+ }
45
+ if (args.length) {
46
+ let index = -1;
47
+ return template.replace(/{(\d+)?}/g, (match, digit) => {
48
+ index++;
49
+ return args[digit || index] ?? match;
50
+ });
51
+ }
52
+ return template;
53
+ };
54
+
package/src/index.ts ADDED
@@ -0,0 +1,42 @@
1
+ export {
2
+ APP_NAME,
3
+ APP_NAME_DASHED,
4
+ APP_NAME_UNDERSCORED,
5
+ IS_DEV_MODE,
6
+ } from './common/env';
7
+
8
+ export type * from './types';
9
+
10
+ export {ComponentRegistry} from './common/ComponentRegistry';
11
+
12
+ export {
13
+ CATCH_ALL,
14
+ JSESSIONID_HEADER,
15
+ PORTAL_COMPONENT_ATTRIBUTE,
16
+ PORTAL_REGION_ATTRIBUTE,
17
+ PROJECT_ID_HEADER,
18
+ RENDER_MODE,
19
+ RENDER_MODE_HEADER,
20
+ XP_BASE_URL_HEADER,
21
+ XP_COMPONENT_TYPE,
22
+ XP_REQUEST_TYPE,
23
+ } from './common/constants';
24
+
25
+
26
+ export {richTextQuery} from './guillotine/metadata/richTextQuery';
27
+ export {validateData} from './guillotine/validateData';
28
+
29
+ export {I18n} from './i18n/i18n';
30
+
31
+ export {getContentApiUrl} from './utils/getContentApiUrl';
32
+ export {getProjectLocaleConfig} from './utils/getProjectLocaleConfig';
33
+ export {getProjectLocaleConfigById} from './utils/getProjectLocaleConfigById';
34
+ export {getProjectLocaleConfigByLocale} from './utils/getProjectLocaleConfigByLocale';
35
+ export {getRequestLocaleInfo} from './utils/getRequestLocaleInfo';
36
+ export {sanitizeGraphqlName} from './utils/sanitizeGraphqlName';
37
+
38
+ export {
39
+ UrlProcessor,
40
+ getAsset,
41
+ getUrl,
42
+ } from './common/UrlProcessor';
@@ -0,0 +1,14 @@
1
+ export const getShortcutQuery = `
2
+ query($path:ID!){
3
+ guillotine {
4
+ get(key:$path) {
5
+ ... on base_Shortcut {
6
+ data {
7
+ target {
8
+ pageUrl(type: absolute)
9
+ }
10
+ }
11
+ }
12
+ }
13
+ }
14
+ }`;
package/src/server.ts ADDED
@@ -0,0 +1,5 @@
1
+ export {fetchContent} from './guillotine/fetchContent';
2
+ export {fetchContentPathsForAllLocales} from './guillotine/fetchContentPathsForAllLocales';
3
+ export {fetchContentPathsForLocale} from './guillotine/fetchContentPathsForLocale';
4
+ export {fetchFromApi} from './guillotine/fetchFromApi';
5
+ export {fetchGuillotine} from './guillotine/fetchGuillotine';
@@ -0,0 +1,147 @@
1
+ import type {XP_COMPONENT_TYPE} from '../common/constants';
2
+ import type {Context} from './next';
3
+
4
+ // Differs from ComponentDefinition to avoid storing catchAll on all components
5
+ // catchAll is calculated in getType instead
6
+ export interface ComponentDefinitionParams {
7
+ query?: SelectedQueryMaybeVariablesFunc
8
+ configQuery?: string
9
+ processor?: DataProcessor
10
+ view?: React.FunctionComponent<any>
11
+ }
12
+
13
+ /**
14
+ * Object that configures the handling of a particular content type. All attributes are optional (see examples below), and missing values will fall back to default behavior:
15
+ * - 'query' (used in fetchContent.ts) Guillotine query for fetching content data, may also have a function that supplies guillotine variables. So, 'query' can EITHER be only a query string, OR also add a get-guillotine-variables function. In the latter case, 'query' can be an object with 'query' and 'variables' attributes, or an array where the query string is first and the get-variables function is second. Either way, the get-variables function takes two arguments: path (content path, mandatory) and context (next.js-supplied Context from getServerSideProps etc. Optional, and requires that fetchContent is called with the context, of course).
16
+ * - 'props' (used in fetchContent.ts) is a function for processing props after fetching them
17
+ * - 'view' (used in BasePage.tsx) is a React component: top-level content-type-specific rendering with the props first fetched from guillotine (and then optionally preprocessed with the function in 'props').
18
+ */
19
+ export interface ComponentDefinition {
20
+ catchAll?: boolean; // will be set automatically depending on the binding
21
+ query?: SelectedQueryMaybeVariablesFunc,
22
+ configQuery?: string,
23
+ processor?: DataProcessor,
24
+ view?: React.FunctionComponent<any>
25
+ }
26
+
27
+ export interface ComponentDescriptor {
28
+ type?: ComponentDefinition;
29
+ component?: PageComponent;
30
+ queryAndVariables?: QueryAndVariables;
31
+ }
32
+
33
+ export type ComponentDictionary = Record<string,ComponentDefinitionParams>;
34
+
35
+ // NB! Always return null or empty object from processor for next is unable to serialize undefined
36
+ export type DataProcessor = (data: any, context?: Context, config?: any) => Promise<Record<string, any>>;
37
+
38
+ export interface FragmentData {
39
+ id: string;
40
+ fragment: {
41
+ components: PageComponent[];
42
+ }
43
+ }
44
+
45
+ export interface ImageData {
46
+ ref: string;
47
+ image: {
48
+ id: string,
49
+ } | null,
50
+ }
51
+
52
+ export interface LayoutData {
53
+ descriptor: string;
54
+ config?: any;
55
+
56
+ [customKeysFromQuery: string]: any;
57
+ }
58
+
59
+ export interface LinkData {
60
+ ref: string,
61
+ media: {
62
+ content: {
63
+ id: string,
64
+ }
65
+ } | null,
66
+ }
67
+
68
+ export type MacroConfig = Record<string, any>;
69
+
70
+ export interface MacroData {
71
+ ref: string
72
+ name: string
73
+ descriptor: string
74
+ config: Record<string, MacroConfig>
75
+ }
76
+
77
+ export interface PageComponent {
78
+ [key: string]: any; // keeps ts happy when accessing component data field by XP_COMPONENT_TYPE type
79
+ type: XP_COMPONENT_TYPE;
80
+ path: string;
81
+ page?: PageData;
82
+ part?: PartData;
83
+ layout?: LayoutData;
84
+ fragment?: FragmentData;
85
+ text?: TextData;
86
+ image?: any;
87
+ regions?: RegionTree;
88
+ data?: any;
89
+ error?: any;
90
+ }
91
+
92
+ export interface PageData {
93
+ descriptor: string;
94
+ config?: any;
95
+ template?: string | null;
96
+ regions?: RegionTree;
97
+ }
98
+
99
+ export interface PageRegion {
100
+ name: string;
101
+ components: PageComponent[];
102
+ }
103
+
104
+ export interface PartData {
105
+ descriptor: string;
106
+ config: any; // TODO NestedRecord?;
107
+
108
+ [customKeysFromQuery: string]: any;
109
+ }
110
+
111
+ export interface QueryAndVariables {
112
+ query: string
113
+ variables?: Record<string, any>
114
+ }
115
+
116
+ export type QueryGetter = (path: string, context?: Context, config?: any) => string;
117
+
118
+ export type SelectedQueryMaybeVariablesFunc =
119
+ | string
120
+ | QueryGetter
121
+ | {
122
+ query: string | QueryGetter
123
+ variables: VariablesGetter
124
+ }
125
+ | [string | QueryGetter, VariablesGetter];
126
+
127
+ export type RegionTree = Record<string, PageRegion>;
128
+
129
+ export interface RichTextData {
130
+ processedHtml: string
131
+ links: LinkData[]
132
+ macros: MacroData[]
133
+ images: ImageData[]
134
+ }
135
+
136
+ export interface TextData {
137
+ value: RichTextData;
138
+ }
139
+
140
+ // TODO: also access as arguments: dataAsJson, pageAsJson, configAsJson from the first (meta) call here?
141
+ // Another option could be to let the component or page controller pass those values to NextJS by a header
142
+ export type VariablesGetter = (path: string, context?: Context, config?: any) => VariablesGetterResult;
143
+
144
+ export interface VariablesGetterResult {
145
+ [variables: string]: any
146
+ path: string
147
+ }
@@ -0,0 +1,142 @@
1
+ import {DOMNode} from 'html-react-parser';
2
+ import type {
3
+ RENDER_MODE,
4
+ XP_REQUEST_TYPE,
5
+ } from '../common/constants';
6
+ import type {
7
+ FragmentData,
8
+ LayoutData,
9
+ MacroConfig,
10
+ MacroData,
11
+ PageComponent,
12
+ PageData,
13
+ PartData,
14
+ RichTextData,
15
+ RegionTree,
16
+ } from './component';
17
+
18
+
19
+ export interface BaseComponentProps {
20
+ component: PageComponent;
21
+ meta: MetaData;
22
+ common?: any; // Content is passed down for optional consumption in componentviews.
23
+ // TODO: Use a react contextprovider instead of "manually" passing everything down
24
+ }
25
+
26
+ export interface BaseLayoutProps {
27
+ component?: LayoutData;
28
+ path: string;
29
+ regions?: RegionTree;
30
+ common?: any;
31
+ meta: MetaData;
32
+ }
33
+
34
+ export interface BaseMacroProps {
35
+ data: MacroData;
36
+ meta: MetaData;
37
+ renderInEditMode?: boolean;
38
+ }
39
+
40
+ export interface BasePageProps {
41
+ component?: PageData;
42
+ path?: string;
43
+ common?: any;
44
+ data?: any;
45
+ error?: string;
46
+ meta: MetaData;
47
+ }
48
+
49
+ export interface BasePartProps {
50
+ component?: PartData;
51
+ path: string;
52
+ common?: any;
53
+ data?: any;
54
+ error?: string;
55
+ meta: MetaData;
56
+ }
57
+
58
+ export interface FragmentProps {
59
+ page?: PageData;
60
+ component?: FragmentData;
61
+ common?: any;
62
+ meta: MetaData;
63
+ }
64
+
65
+ export interface LayoutProps {
66
+ layout: LayoutData;
67
+ path: string;
68
+ common: any;
69
+ meta: MetaData;
70
+ }
71
+
72
+ export interface MacroProps {
73
+ name: string;
74
+ config: MacroConfig;
75
+ meta: MetaData;
76
+ }
77
+
78
+ export interface MetaData {
79
+ type: string,
80
+ path: string,
81
+ requestType: XP_REQUEST_TYPE,
82
+ renderMode: RENDER_MODE,
83
+ requestedComponent?: PageComponent,
84
+ canRender: boolean,
85
+ catchAll: boolean,
86
+ apiUrl: string,
87
+ baseUrl: string,
88
+ locale: string,
89
+ defaultLocale: string,
90
+ }
91
+
92
+ export interface PageProps {
93
+ page: PageData;
94
+ path: string;
95
+ data?: any;
96
+ common?: any; // Content is passed down to componentviews. TODO: Use a react contextprovider instead?
97
+ meta: MetaData;
98
+ }
99
+
100
+ export interface PartProps {
101
+ part: PartData
102
+ path: string
103
+ data?: any
104
+ // Content is passed down to componentviews. TODO: Use a react contextprovider instead?
105
+ common?: any
106
+ meta: MetaData
107
+ }
108
+
109
+ export interface RegionProps {
110
+ name: string
111
+ components?: PageComponent[]
112
+ className?: string
113
+ // Content is passed down for optional consumption in componentviews. TODO: Use a react contextprovider instead?
114
+ common?: any
115
+ meta: MetaData
116
+ }
117
+
118
+ export interface RegionsProps {
119
+ page: PageData | null;
120
+ name?: string;
121
+ // Content is passed down for optional consumption in componentviews. TODO: Use a react contextprovider instead?
122
+ common?: any;
123
+ meta: MetaData;
124
+ }
125
+
126
+ export type Replacer = (
127
+ domNode: DOMNode,
128
+ data: RichTextData,
129
+ meta: MetaData,
130
+ renderMacroInEditMode: boolean
131
+ ) => ReplacerResult;
132
+
133
+ export type ReplacerResult = JSX.Element | object | void | undefined | null | false;
134
+
135
+ export interface RichTextViewProps {
136
+ data: RichTextData
137
+ meta: MetaData
138
+ className?: string
139
+ tag?: string
140
+ renderMacroInEditMode?: boolean
141
+ customReplacer?: Replacer
142
+ }