create-sitecore-jss 22.2.0-canary.9 → 22.3.0-canary.2

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 (129) hide show
  1. package/dist/bin.js +17 -43
  2. package/dist/common/processes/next.js +4 -1
  3. package/dist/common/processes/transform.js +2 -12
  4. package/dist/common/prompts/base.js +0 -13
  5. package/dist/common/prompts/proxy.js +35 -0
  6. package/dist/common/prompts/sxp.js +16 -2
  7. package/dist/common/utils/helpers.js +27 -2
  8. package/dist/init-runner.js +1 -1
  9. package/dist/initializers/angular/prompts.js +4 -4
  10. package/dist/initializers/angular-xmcloud/index.js +21 -7
  11. package/dist/initializers/node-xmcloud-proxy/index.js +2 -1
  12. package/dist/templates/angular/.env +4 -5
  13. package/dist/templates/angular/.eslintrc +1 -0
  14. package/dist/templates/angular/gitignore +5 -0
  15. package/dist/templates/angular/package.json +6 -8
  16. package/dist/templates/angular/scripts/config/plugins/fallback.ts +0 -1
  17. package/dist/templates/angular/scripts/generate-component-factory/index.ts +45 -0
  18. package/dist/templates/angular/scripts/generate-component-factory/plugins/component-factory.ts +147 -0
  19. package/dist/templates/angular/scripts/generate-component-factory/plugins/components.ts +19 -0
  20. package/dist/templates/angular/scripts/generate-component-factory/plugins/packages.ts +29 -0
  21. package/dist/templates/angular/scripts/generate-component-factory/template.ts +46 -0
  22. package/dist/templates/angular/scripts/generate-config.ts +25 -6
  23. package/dist/templates/angular/scripts/generate-plugins.ts +5 -0
  24. package/dist/templates/angular/scripts/update-graphql-fragment-data.ts +21 -30
  25. package/dist/templates/angular/server.bundle.ts +3 -23
  26. package/dist/templates/angular/server.exports.ts +13 -0
  27. package/dist/templates/angular/src/app/JssState.ts +2 -9
  28. package/dist/templates/angular/src/app/app.module.ts +5 -4
  29. package/dist/templates/angular/src/app/app.server.module.ts +9 -6
  30. package/dist/templates/angular/src/app/components/gitignore +1 -1
  31. package/dist/templates/angular/src/app/i18n/jss-translation-client-loader.service.ts +15 -7
  32. package/dist/templates/angular/src/app/i18n/jss-translation-server-loader.service.ts +14 -2
  33. package/dist/templates/angular/src/app/jss-context.server-side.service.ts +4 -2
  34. package/dist/templates/angular/src/app/jss-context.service.ts +14 -11
  35. package/dist/templates/angular/src/app/jss-graphql.service.ts +7 -7
  36. package/dist/templates/angular/src/app/layout/jss-layout.service.ts +2 -2
  37. package/dist/templates/angular/src/app/lib/dictionary-service-factory.ts +4 -1
  38. package/dist/templates/angular/src/app/lib/graphql-client-factory/config.ts +21 -0
  39. package/dist/templates/angular/src/app/lib/graphql-client-factory/index.ts +16 -0
  40. package/dist/templates/angular/src/app/lib/layout-service-factory.ts +1 -1
  41. package/dist/templates/angular/src/app/routing/layout/layout.component.ts +10 -9
  42. package/dist/templates/angular/src/environments/gitignore +2 -1
  43. package/dist/templates/angular-sxp/.env +2 -0
  44. package/dist/templates/angular-sxp/scripts/config/plugins/disconnected.ts +4 -2
  45. package/dist/templates/angular-sxp/src/app/components/graph-ql-layout/graph-ql-layout.component.ts +1 -1
  46. package/dist/templates/angular-xmcloud/.env +15 -2
  47. package/dist/templates/angular-xmcloud/angular.json +0 -1
  48. package/dist/templates/angular-xmcloud/package.json +2 -0
  49. package/dist/templates/angular-xmcloud/scripts/bootstrap.ts +28 -0
  50. package/dist/templates/angular-xmcloud/scripts/config/plugins/xmcloud.ts +16 -0
  51. package/dist/templates/angular-xmcloud/scripts/generate-component-factory/plugins/packages.ts +34 -0
  52. package/dist/templates/angular-xmcloud/scripts/generate-component-factory/template.ts +57 -0
  53. package/dist/templates/angular-xmcloud/scripts/generate-metadata.ts +25 -0
  54. package/dist/templates/angular-xmcloud/server.exports.ts +24 -0
  55. package/dist/templates/angular-xmcloud/src/app/components/app-components.shared.module.ts +21 -0
  56. package/dist/templates/angular-xmcloud/src/app/components/column-splitter/column-splitter.component.html +5 -0
  57. package/dist/templates/angular-xmcloud/src/app/components/column-splitter/column-splitter.component.ts +40 -0
  58. package/dist/templates/angular-xmcloud/src/app/components/container/container.component.html +2 -3
  59. package/dist/templates/angular-xmcloud/src/app/components/image/image.component.html +36 -0
  60. package/dist/templates/angular-xmcloud/src/app/components/image/image.component.ts +67 -0
  61. package/dist/templates/angular-xmcloud/src/app/components/link-list/link-list.component.html +15 -0
  62. package/dist/templates/angular-xmcloud/src/app/components/link-list/link-list.component.ts +41 -0
  63. package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation-item.component.html +23 -0
  64. package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation-item.component.ts +65 -0
  65. package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation.component.html +21 -0
  66. package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation.component.ts +49 -0
  67. package/dist/templates/angular-xmcloud/src/app/components/page-content/page-content.component.html +5 -0
  68. package/dist/templates/angular-xmcloud/src/app/components/page-content/page-content.component.ts +39 -0
  69. package/dist/templates/angular-xmcloud/src/app/components/partial-design-dynamic-placeholder/partial-design-dynamic-placeholder.component.html +1 -0
  70. package/dist/templates/angular-xmcloud/src/app/components/partial-design-dynamic-placeholder/partial-design-dynamic-placeholder.component.ts +15 -0
  71. package/dist/templates/angular-xmcloud/src/app/components/promo/promo.component.html +21 -0
  72. package/dist/templates/angular-xmcloud/src/app/components/promo/promo.component.ts +13 -0
  73. package/dist/templates/angular-xmcloud/src/app/components/richtext/richtext.component.html +7 -12
  74. package/dist/templates/angular-xmcloud/src/app/components/richtext/richtext.component.ts +6 -1
  75. package/dist/templates/angular-xmcloud/src/app/components/row-splitter/row-splitter.component.html +11 -0
  76. package/dist/templates/angular-xmcloud/src/app/components/row-splitter/row-splitter.component.ts +35 -0
  77. package/dist/templates/angular-xmcloud/src/app/components/sxa.component.ts +3 -3
  78. package/dist/templates/angular-xmcloud/src/app/components/title/title.component.html +10 -0
  79. package/dist/templates/angular-xmcloud/src/app/components/title/title.component.ts +56 -0
  80. package/dist/templates/angular-xmcloud/src/app/jss-link.service.ts +55 -0
  81. package/dist/templates/angular-xmcloud/src/app/lib/config.ts +2 -0
  82. package/dist/templates/angular-xmcloud/src/app/lib/graphql-client-factory/config.ts +58 -0
  83. package/dist/templates/angular-xmcloud/src/app/routing/layout/layout.component.html +38 -0
  84. package/dist/templates/angular-xmcloud/src/app/routing/layout/layout.component.ts +104 -0
  85. package/dist/templates/angular-xmcloud/src/app/routing/scripts/cdp-page-view.component.ts +77 -0
  86. package/dist/templates/angular-xmcloud/src/app/routing/scripts/cloud-sdk-init.component.ts +48 -0
  87. package/dist/templates/angular-xmcloud/src/app/routing/scripts/scripts.component.html +5 -0
  88. package/dist/templates/angular-xmcloud/src/app/routing/scripts/scripts.module.ts +12 -0
  89. package/dist/templates/angular-xmcloud/src/assets/styles/basic/_header.scss +3 -1
  90. package/dist/templates/angular-xmcloud/src/assets/styles/main.scss +10 -0
  91. package/dist/templates/nextjs/package.json +5 -5
  92. package/dist/templates/nextjs/scripts/config/plugins/fallback.ts +0 -1
  93. package/dist/templates/nextjs/scripts/generate-config.ts +8 -1
  94. package/dist/templates/nextjs/src/lib/page-props-factory/plugins/component-props.ts +2 -1
  95. package/dist/templates/nextjs-styleguide/package.json +1 -1
  96. package/dist/templates/nextjs-styleguide/scripts/config/plugins/disconnected.ts +1 -0
  97. package/dist/templates/nextjs-sxa/src/assets/sass/components/common/_alignment.scss +34 -7
  98. package/dist/templates/nextjs-sxa/src/components/Container.tsx +6 -14
  99. package/dist/templates/nextjs-xmcloud/package.json +3 -2
  100. package/dist/templates/nextjs-xmcloud/src/Bootstrap.tsx +25 -10
  101. package/dist/templates/nextjs-xmcloud/src/byoc/{index.ts → index.tsx} +25 -8
  102. package/dist/templates/nextjs-xmcloud/src/components/CdpPageView.tsx +9 -14
  103. package/dist/templates/nextjs-xmcloud/src/lib/page-props-factory/plugins/component-themes.ts +2 -1
  104. package/dist/templates/nextjs-xmcloud/src/lib/page-props-factory/plugins/preview-mode.ts +2 -1
  105. package/dist/templates/node-headless-ssr-experience-edge/gitignore +19 -0
  106. package/dist/templates/node-headless-ssr-experience-edge/package.json +2 -2
  107. package/dist/templates/node-headless-ssr-proxy/gitignore +19 -0
  108. package/dist/templates/node-headless-ssr-proxy/package.json +3 -3
  109. package/dist/templates/node-headless-ssr-proxy/src/config.ts +3 -3
  110. package/dist/templates/node-headless-ssr-proxy/src/httpAgents.ts +2 -2
  111. package/dist/templates/node-headless-ssr-proxy/src/index.ts +9 -2
  112. package/dist/templates/node-xmcloud-proxy/.env +7 -1
  113. package/dist/templates/node-xmcloud-proxy/README.md +1 -1
  114. package/dist/templates/node-xmcloud-proxy/gitignore +33 -0
  115. package/dist/templates/node-xmcloud-proxy/package.json +3 -2
  116. package/dist/templates/node-xmcloud-proxy/src/config.ts +9 -3
  117. package/dist/templates/node-xmcloud-proxy/src/index.ts +54 -5
  118. package/dist/templates/node-xmcloud-proxy/src/types.ts +10 -42
  119. package/dist/templates/react/package.json +5 -5
  120. package/dist/templates/react/scripts/generate-config.js +10 -3
  121. package/dist/templates/react-native/package.json +4 -4
  122. package/dist/templates/vue/package.json +4 -4
  123. package/dist/templates/vue/scripts/generate-config.js +5 -0
  124. package/package.json +2 -2
  125. package/dist/templates/angular/scripts/generate-component-factory.ts +0 -166
  126. package/dist/templates/angular/src/app/lib/graphql-client-factory.ts +0 -28
  127. package/dist/templates/angular-xmcloud/src/app/lib/graphql-client-factory.ts +0 -44
  128. package/dist/templates/nextjs-xmcloud/src/lib/context/index.ts +0 -22
  129. package/dist/templates/nextjs-xmcloud/src/lib/context/sdk/events.ts +0 -26
@@ -0,0 +1,147 @@
1
+
2
+ import * as fs from 'fs';
3
+ import path from 'path';
4
+ import chokidar from 'chokidar';
5
+ import { componentFactoryTemplate } from '../template';
6
+ import {
7
+ ComponentFactoryPluginConfig,
8
+ ComponentFactoryPlugin as ComponentFactoryPluginType,
9
+ } from '..';
10
+
11
+ export interface PackageDefinition {
12
+ name: string;
13
+ components: {
14
+ moduleName: string;
15
+ componentName: string;
16
+ }[];
17
+ }
18
+
19
+ const componentFactoryPath = path.resolve('src/app/components/app-components.module.ts');
20
+ const componentRootPath = 'src/app/components';
21
+
22
+ function watchComponentFactory(config: ComponentFactoryPluginConfig) {
23
+ console.log(`Watching for changes to component factory sources in ${componentRootPath}...`);
24
+
25
+ chokidar
26
+ .watch(componentRootPath, { ignoreInitial: true, awaitWriteFinish: true })
27
+ .on('add', writeComponentFactory.bind(null, config))
28
+ .on('unlink', writeComponentFactory.bind(null, config));
29
+ }
30
+
31
+ function writeComponentFactory(config: ComponentFactoryPluginConfig) {
32
+ const componentFactory = generateComponentFactory(config);
33
+
34
+ console.log(`Writing component factory to ${componentFactoryPath}`);
35
+
36
+ fs.writeFileSync(componentFactoryPath, componentFactory, { encoding: 'utf8' });
37
+ }
38
+
39
+ function generateComponentFactory(config: ComponentFactoryPluginConfig) {
40
+ // By convention, we expect to find Angular components
41
+ // under /src/app/components/component-name/component-name.component.ts
42
+ // If a component-name.module.ts file exists, we will treat it as lazy loaded.
43
+ // If you'd like to use your own convention, encode it below.
44
+ // NOTE: generating the component factory module is also totally optional,
45
+ // and it can be maintained manually if preferred.
46
+
47
+ const imports: string[] = [];
48
+ const registrations: string[] = [];
49
+ const lazyRegistrations: string[] = [];
50
+ const declarations: string[] = [];
51
+
52
+ config.packages.forEach((p) => {
53
+ const variables = p.components
54
+ .map((c) => {
55
+ registrations.push(`{ name: '${c.componentName}', type: ${c.moduleName} },`);
56
+ config.components.push(c.componentName);
57
+
58
+ return c.moduleName;
59
+ })
60
+ .join(', ');
61
+ imports.push(`import { ${variables} } from '${p.name}'`);
62
+ });
63
+
64
+ fs.readdirSync(componentRootPath).forEach((componentFolder) => {
65
+ // ignore ts files in component root folder
66
+ if (componentFolder.endsWith('.ts') || componentFolder === '.gitignore') {
67
+ return;
68
+ }
69
+
70
+ const componentFilePath = path.join(
71
+ componentRootPath,
72
+ componentFolder,
73
+ `${componentFolder}.component.ts`
74
+ );
75
+
76
+ if (!fs.existsSync(componentFilePath)) {
77
+ return;
78
+ }
79
+
80
+ const componentFileContents = fs.readFileSync(componentFilePath, 'utf8');
81
+
82
+ // ASSUMPTION: your component should export a class directly that follows Angular conventions,
83
+ // i.e. `export class FooComponent` - so we can detect the component's name for auto registration.
84
+ const componentClassMatch = /export class (.+?)Component\b/g.exec(componentFileContents);
85
+
86
+ if (componentClassMatch === null) {
87
+ console.debug(
88
+ `Component ${componentFilePath} did not seem to export a component class. It will be skipped.`
89
+ );
90
+ return;
91
+ }
92
+
93
+ const componentName = componentClassMatch[1];
94
+ const importVarName = `${componentName}Component`;
95
+
96
+ config.components.push(componentName);
97
+
98
+ // check for lazy loading needs
99
+ const moduleFilePath = path.join(
100
+ componentRootPath,
101
+ componentFolder,
102
+ `${componentFolder}.module.ts`
103
+ );
104
+ const isLazyLoaded = fs.existsSync(moduleFilePath);
105
+
106
+ if (isLazyLoaded) {
107
+ console.debug(`Registering JSS component (lazy) ${componentName}`);
108
+ lazyRegistrations.push(
109
+ `{ path: '${componentName}', loadChildren: () => import('./${componentFolder}/${componentFolder}.module').then(m => m.${componentName}Module) },`
110
+ );
111
+ } else {
112
+ console.debug(`Registering JSS component ${componentName}`);
113
+ imports.push(
114
+ `import { ${importVarName} } from './${componentFolder}/${componentFolder}.component';`
115
+ );
116
+ registrations.push(`{ name: '${componentName}', type: ${importVarName} },`);
117
+ declarations.push(`${importVarName},`);
118
+ }
119
+ });
120
+
121
+ return componentFactoryTemplate({
122
+ imports,
123
+ components: config.components,
124
+ registrations,
125
+ lazyRegistrations,
126
+ declarations,
127
+ });
128
+ }
129
+
130
+ /**
131
+ * Generates the component factory file.
132
+ */
133
+ class ComponentFactoryPlugin implements ComponentFactoryPluginType {
134
+ order = 9999;
135
+
136
+ exec(config: ComponentFactoryPluginConfig) {
137
+ if (config.watch) {
138
+ watchComponentFactory(config);
139
+ } else {
140
+ writeComponentFactory(config);
141
+ }
142
+
143
+ return config;
144
+ }
145
+ }
146
+
147
+ export const componentFactoryPlugin = new ComponentFactoryPlugin();
@@ -0,0 +1,19 @@
1
+ import { ComponentFactoryPlugin, ComponentFactoryPluginConfig } from '..';
2
+
3
+ /**
4
+ * Provides custom components configuration
5
+ */
6
+ class ComponentsPlugin implements ComponentFactoryPlugin {
7
+ order = 0;
8
+
9
+ exec(config: ComponentFactoryPluginConfig) {
10
+ /**
11
+ * You can specify components which you want to import using custom path
12
+ */
13
+ config.components = [];
14
+
15
+ return config;
16
+ }
17
+ }
18
+
19
+ export const componentsPlugin = new ComponentsPlugin();
@@ -0,0 +1,29 @@
1
+ import { ComponentFactoryPlugin, ComponentFactoryPluginConfig } from '..';
2
+
3
+ /**
4
+ * Provides custom packages configuration
5
+ */
6
+ class PackagesPlugin implements ComponentFactoryPlugin {
7
+ order = 0;
8
+
9
+ exec(config: ComponentFactoryPluginConfig) {
10
+ /**
11
+ * You can specify components which you want to import from external/internal packages
12
+ * in format:
13
+ * {
14
+ * name: 'package name',
15
+ * components: [
16
+ * {
17
+ * componentName: 'component name', // component rendering name,
18
+ * moduleName: 'module name' // component name to import from the package
19
+ * }
20
+ * ]
21
+ * }
22
+ */
23
+ config.packages = [];
24
+
25
+ return config;
26
+ }
27
+ }
28
+
29
+ export const packagesPlugin = new PackagesPlugin();
@@ -0,0 +1,46 @@
1
+ export const componentFactoryTemplate = ({
2
+ imports,
3
+ components,
4
+ registrations,
5
+ lazyRegistrations,
6
+ declarations,
7
+ }: {
8
+ imports: string[];
9
+ components: string[];
10
+ registrations: string[];
11
+ lazyRegistrations: string[];
12
+ declarations: string[];
13
+ }) => `// Do not edit this file, it is auto-generated at build time!
14
+ // See scripts/generate-component-factory/index.ts to modify the generation of this file.
15
+ // Use app-components.shared.module.ts to modify the imports, etc of this module.
16
+ // Note: code-generation is optional! See ./.gitignore for directions to remove it,
17
+ // if you do not want it.
18
+
19
+ import { NgModule } from '@angular/core';
20
+ import { JssModule } from '@sitecore-jss/sitecore-jss-angular';
21
+ import { AppComponentsSharedModule } from './app-components.shared.module';
22
+ ${imports.join('\n')}
23
+
24
+ export const components = [
25
+ ${components.map((c) => `'${c}'`).join(',\n ')}
26
+ ];
27
+
28
+ @NgModule({
29
+ imports: [
30
+ AppComponentsSharedModule,
31
+ JssModule.withComponents([
32
+ ${registrations.join('\n ')}
33
+ ], [
34
+ ${lazyRegistrations.join('\n ')}
35
+ ]),
36
+ ],
37
+ exports: [
38
+ JssModule,
39
+ AppComponentsSharedModule,
40
+ ],
41
+ declarations: [
42
+ ${declarations.join('\n ')}
43
+ ],
44
+ })
45
+ export class AppComponentsModule { }
46
+ `;
@@ -1,3 +1,4 @@
1
+ import 'dotenv/config';
1
2
  import * as fs from 'fs';
2
3
  import * as path from 'path';
3
4
  import { constantCase } from 'constant-case';
@@ -23,8 +24,16 @@ const defaultConfigValue: JssConfig = {
23
24
  defaultServerRoute: '/',
24
25
  };
25
26
 
26
- generateConfig('src/environments/environment.js', defaultConfigValue, { production: false });
27
- generateConfig('src/environments/environment.prod.js', defaultConfigValue, { production: true });
27
+ async function main() {
28
+ await generateConfig('src/environments/environment.js', defaultConfigValue, {
29
+ production: false,
30
+ });
31
+ await generateConfig('src/environments/environment.prod.js', defaultConfigValue, {
32
+ production: true,
33
+ });
34
+ }
35
+
36
+ main();
28
37
 
29
38
  /**
30
39
  * Generates the JSS config based on config plugins (under ./config/plugins)
@@ -38,7 +47,15 @@ export function generateConfig(
38
47
  defaultConfig: JssConfig = defaultConfigValue,
39
48
  configOverrides?: { [key: string]: unknown }
40
49
  ) {
41
- jssConfigFactory
50
+ // Handle undefined values
51
+ defaultConfig = Object.keys(defaultConfig).reduce((acc, key) => {
52
+ return {
53
+ ...acc,
54
+ [key]: defaultConfig[key] || '',
55
+ };
56
+ }, {});
57
+
58
+ return jssConfigFactory
42
59
  .create(defaultConfig)
43
60
  .then((config) => {
44
61
  writeConfig(Object.assign(config, configOverrides), outputPath);
@@ -67,9 +84,11 @@ export function writeConfig(config: JssConfig, outputPath?: string) {
67
84
 
68
85
  // Set base configuration values, allowing override with environment variables
69
86
  Object.keys(config).forEach((prop) => {
70
- configText += `config.${prop} = process.env.${constantCase(prop)} || "${config[prop]
71
- ?.toString()
72
- .trim()}";\n`;
87
+ // Handle undefined values
88
+ const value = config[prop] || '';
89
+ configText += `config.${prop} = process.env.${constantCase(
90
+ prop
91
+ )} || "${value.toString().trim()}";\n`;
73
92
  });
74
93
 
75
94
  configText += `module.exports.environment = config;`;
@@ -21,6 +21,11 @@ const pluginDefinitions: PluginDefinition[] = [
21
21
  rootPath: 'scripts/config/plugins',
22
22
  moduleType: ModuleType.ESM,
23
23
  },
24
+ {
25
+ distPath: 'scripts/temp/generate-component-factory-plugins.ts',
26
+ rootPath: 'scripts/generate-component-factory/plugins',
27
+ moduleType: ModuleType.ESM,
28
+ },
24
29
  ];
25
30
 
26
31
  pluginDefinitions.forEach((definition) => {
@@ -1,6 +1,6 @@
1
- import * as fetch from 'isomorphic-fetch';
2
1
  import * as fs from 'fs';
3
- import { generateConfig } from './generate-config';
2
+ import clientFactory from 'lib/graphql-client-factory';
3
+ import { getGraphQLClientFactoryConfig } from 'lib/graphql-client-factory/config';
4
4
 
5
5
  // Apollo Client supports caching GraphQL responses, which can greatly reduce network traffic needs.
6
6
  // In order to work correctly with interfaces in GraphQL, it needs to know some basic information about
@@ -9,28 +9,23 @@ import { generateConfig } from './generate-config';
9
9
  //
10
10
  // The `jss graphql:update` command should be executed when Sitecore templates related to the site are altered.
11
11
 
12
- generateConfig('src/environments/environment.js');
12
+ import './generate-config';
13
13
 
14
- let jssConfig;
14
+ const clientFactoryConfig = getGraphQLClientFactoryConfig();
15
15
 
16
- try {
17
- jssConfig = require('../src/environments/environment').environment;
18
- } catch (e) {
19
- console.error(
20
- 'Unable to require JSS config. Ensure `jss setup` has been run, and the app has been started at least once after setup.'
21
- );
22
- console.error(e);
23
- process.exit(1);
24
- }
16
+ console.log(`Updating GraphQL fragment type data from ${clientFactoryConfig.endpoint}...`);
25
17
 
26
- console.log(`Updating GraphQL fragment type data from ${jssConfig.graphQLEndpoint}...`);
27
-
28
- fetch(jssConfig.graphQLEndpoint, {
29
- method: 'POST',
30
- headers: { 'Content-Type': 'application/json', sc_apikey: jssConfig.sitecoreApiKey },
31
- body: JSON.stringify({
32
- query: `
33
- {
18
+ clientFactory()
19
+ .request<{
20
+ [key: string]: unknown;
21
+ __schema: {
22
+ kind: string;
23
+ name: string;
24
+ types: { possibleTypes?: { name: string } }[];
25
+ };
26
+ }>(
27
+ `
28
+ {
34
29
  __schema {
35
30
  types {
36
31
  kind
@@ -41,22 +36,18 @@ fetch(jssConfig.graphQLEndpoint, {
41
36
  }
42
37
  }
43
38
  }
44
- `,
45
- }),
46
- })
47
- .then((result) => result.json())
39
+ `
40
+ )
48
41
  .then((result) => {
49
42
  // here we're filtering out any type information unrelated to unions or interfaces
50
- const filteredData = result.data.__schema.types.filter(
51
- (type: { possibleTypes: Array<string> }) => type.possibleTypes !== null
52
- );
43
+ const filteredData = result.__schema.types.filter((type) => type.possibleTypes !== null);
53
44
 
54
45
  const filteredResult = { ...result };
55
- filteredResult.data.__schema.types = filteredData;
46
+ filteredResult.__schema.types = filteredData;
56
47
 
57
48
  fs.writeFile(
58
49
  './src/graphql-fragment-types.ts',
59
- `export default ${JSON.stringify(filteredResult.data, null, 2)}`,
50
+ `export default ${JSON.stringify(filteredResult, null, 2)}`,
60
51
  (err) => {
61
52
  if (err) {
62
53
  console.error('Error writing GraphQLFragmentTypes file', err);
@@ -4,14 +4,12 @@ import { join } from 'path';
4
4
  import 'reflect-metadata';
5
5
  import 'zone.js';
6
6
  import { JssRouteBuilderService } from './src/app/routing/jss-route-builder.service';
7
- import { environment } from './src/environments/environment';
8
7
  import { AppServerModule, renderModule } from './src/main.server';
9
- import { clientFactory } from './src/app/lib/graphql-client-factory';
10
- import { dictionaryServiceFactory } from './src/app/lib/dictionary-service-factory';
11
- import { layoutServiceFactory } from './src/app/lib/layout-service-factory';
12
8
 
13
9
  export * from './src/main.server';
14
10
 
11
+ export * from './server.exports';
12
+
15
13
  const http = require('http');
16
14
  const https = require('https');
17
15
 
@@ -100,22 +98,4 @@ function parseRouteUrl(url: string) {
100
98
  };
101
99
  }
102
100
 
103
- const apiKey = environment.sitecoreApiKey;
104
- const siteName = environment.sitecoreSiteName;
105
- const defaultLanguage = environment.defaultLanguage;
106
- const graphQLEndpointPath = environment.graphQLEndpointPath;
107
- const graphQLEndpoint = environment.graphQLEndpoint;
108
-
109
- export {
110
- renderView,
111
- parseRouteUrl,
112
- setUpDefaultAgents,
113
- apiKey,
114
- siteName,
115
- clientFactory,
116
- dictionaryServiceFactory,
117
- layoutServiceFactory,
118
- defaultLanguage,
119
- graphQLEndpointPath,
120
- graphQLEndpoint,
121
- };
101
+ export { renderView, parseRouteUrl, setUpDefaultAgents };
@@ -0,0 +1,13 @@
1
+ import { environment } from './src/environments/environment';
2
+
3
+ /**
4
+ * Define the required configuration values to be exported from the server.bundle.ts.
5
+ */
6
+
7
+ const apiKey = environment.sitecoreApiKey;
8
+ const siteName = environment.sitecoreSiteName;
9
+
10
+ export {
11
+ apiKey,
12
+ siteName,
13
+ };
@@ -1,15 +1,8 @@
1
- import {
2
- RouteData,
3
- LayoutServiceContextData,
4
- } from '@sitecore-jss/sitecore-jss-angular';
1
+ import { BaseJssState } from '@sitecore-jss/sitecore-jss-angular';
5
2
  import { LayoutServiceError } from './layout/jss-layout.service';
6
3
 
7
- export class JssState<Fields = Record<string, unknown>> {
4
+ export class JssState extends BaseJssState {
8
5
  language: string;
9
6
  serverRoute: string;
10
7
  routeFetchError?: LayoutServiceError;
11
- sitecore?: LayoutServiceContextData & {
12
- route: RouteData<Fields>;
13
- };
14
- viewBag: { [key: string]: unknown };
15
8
  }
@@ -1,9 +1,8 @@
1
1
  import { APP_ID, NgModule, TransferState } from '@angular/core';
2
2
  import { APP_BASE_HREF } from '@angular/common';
3
- import { HttpClientModule, HttpClient } from '@angular/common/http';
3
+ import { HttpClientModule } from '@angular/common/http';
4
4
  import { RoutingModule } from './routing/routing.module';
5
5
  import { JssLayoutService } from './layout/jss-layout.service';
6
- import { JssContextService } from './jss-context.service';
7
6
  import { AppComponentsModule } from './components/app-components.module';
8
7
  import { AppComponent } from './app.component';
9
8
  import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
@@ -11,6 +10,7 @@ import { JssTranslationClientLoaderService } from './i18n/jss-translation-client
11
10
  import { JssTranslationLoaderService } from './i18n/jss-translation-loader.service';
12
11
  import { GraphQLModule } from './jss-graphql.module';
13
12
  import { JssMetaService } from './jss-meta.service';
13
+ import { JssContextService } from './jss-context.service';
14
14
 
15
15
  @NgModule({
16
16
  imports: [
@@ -20,8 +20,9 @@ import { JssMetaService } from './jss-meta.service';
20
20
  TranslateModule.forRoot({
21
21
  loader: {
22
22
  provide: TranslateLoader,
23
- useFactory: () => new JssTranslationClientLoaderService(new JssTranslationLoaderService()),
24
- deps: [HttpClient, TransferState],
23
+ useFactory: (transferState: TransferState) =>
24
+ new JssTranslationClientLoaderService(new JssTranslationLoaderService(), transferState),
25
+ deps: [TransferState],
25
26
  },
26
27
  }),
27
28
  AppComponentsModule,
@@ -1,4 +1,4 @@
1
- import { NgModule } from '@angular/core';
1
+ import { NgModule, TransferState } from '@angular/core';
2
2
  import { ServerModule } from '@angular/platform-server';
3
3
  import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
4
4
 
@@ -18,11 +18,14 @@ import { JssTranslationServerLoaderService } from './i18n/jss-translation-server
18
18
  // <-- *Important* to get translation values server-side
19
19
  loader: {
20
20
  provide: TranslateLoader,
21
- useFactory: (ssrViewBag: {
22
- [key: string]: unknown;
23
- dictionary: { [key: string]: string };
24
- }) => new JssTranslationServerLoaderService(ssrViewBag),
25
- deps: ['JSS_SERVER_VIEWBAG'],
21
+ useFactory: (
22
+ ssrViewBag: {
23
+ [key: string]: unknown;
24
+ dictionary: { [key: string]: string };
25
+ },
26
+ transferState: TransferState
27
+ ) => new JssTranslationServerLoaderService(ssrViewBag, transferState),
28
+ deps: ['JSS_SERVER_VIEWBAG', TransferState],
26
29
  },
27
30
  }),
28
31
  ],
@@ -1,7 +1,7 @@
1
1
  # App component module is auto-generated by default.
2
2
  # To manually maintain the module,
3
3
  # - Remove this ignore file
4
- # - Delete /scripts/generate-component-factory.ts
4
+ # - Delete /scripts/generate-component-factory/index.ts
5
5
  # - Remove the reference from /scripts/bootstrap.ts
6
6
  # - Consider merging app-components.shared and app-components modules
7
7
  app-components.module.ts
@@ -1,16 +1,24 @@
1
- import { makeStateKey, Injectable } from '@angular/core';
1
+ import { Injectable, TransferState } from '@angular/core';
2
2
  import { TranslateLoader } from '@ngx-translate/core';
3
- import { EMPTY } from 'rxjs';
4
-
5
- export const dictionaryStateKey = makeStateKey('jssDictionary');
3
+ import { DictionaryPhrases } from '@sitecore-jss/sitecore-jss-angular';
4
+ import { EMPTY, Observable, of } from 'rxjs';
5
+ import { JssTranslationLoaderService } from './jss-translation-loader.service';
6
+ import { dictionaryStateKey } from './jss-translation-server-loader.service';
6
7
 
7
8
  @Injectable()
8
9
  export class JssTranslationClientLoaderService implements TranslateLoader {
9
10
  constructor(
10
- private fallbackLoader: TranslateLoader,
11
- ) { }
11
+ private fallbackLoader: JssTranslationLoaderService,
12
+ private transferState: TransferState
13
+ ) {}
14
+
15
+ getTranslation(lang: string): Observable<DictionaryPhrases> {
16
+ const dictionary = this.transferState.get(dictionaryStateKey, null);
17
+
18
+ if (dictionary) {
19
+ return of(dictionary);
20
+ }
12
21
 
13
- getTranslation(lang: string) {
14
22
  if (!this.fallbackLoader) {
15
23
  return EMPTY;
16
24
  }
@@ -1,17 +1,29 @@
1
- import { Inject, Injectable } from '@angular/core';
1
+ import { Inject, Injectable, makeStateKey, StateKey, TransferState } from '@angular/core';
2
2
  import { TranslateLoader } from '@ngx-translate/core';
3
+ import { DictionaryPhrases } from '@sitecore-jss/sitecore-jss-angular';
3
4
  import { of as observableOf, EMPTY } from 'rxjs';
4
5
 
6
+ export const dictionaryStateKey: StateKey<DictionaryPhrases> = makeStateKey<DictionaryPhrases>(
7
+ 'dictionary'
8
+ );
9
+
5
10
  @Injectable()
6
11
  export class JssTranslationServerLoaderService implements TranslateLoader {
7
12
  constructor(
8
13
  // this initial state from sitecore is injected by server.bundle for "integrated" mode
9
14
  @Inject('JSS_SERVER_VIEWBAG')
10
- private serverViewBag: { [key: string]: unknown; dictionary: { [key: string]: string } }
15
+ private serverViewBag: { [key: string]: unknown; dictionary: DictionaryPhrases },
16
+ private transferState: TransferState
11
17
  ) {}
12
18
  getTranslation(_lang: string) {
13
19
  // read initial dictionary from data injected via server.bundle wrapper
14
20
  const dictionary = this.serverViewBag.dictionary;
21
+
22
+ // set the dictionary in transfer state for the client
23
+ // since for ng-translate there is no obvious way to pass the server side dictionary to the client
24
+ // https://github.com/ngx-translate/core/issues/1207#issuecomment-700741671
25
+ this.transferState.set(dictionaryStateKey, dictionary);
26
+
15
27
  if (dictionary) {
16
28
  return observableOf(dictionary);
17
29
  }
@@ -3,6 +3,7 @@ import { JssContextService, jssKey } from './jss-context.service';
3
3
  import { JssState } from './JssState';
4
4
  import { Observable, of as observableOf } from 'rxjs';
5
5
  import { JssLayoutService } from './layout/jss-layout.service';
6
+ import { JssStateService } from '@sitecore-jss/sitecore-jss-angular';
6
7
 
7
8
  /**
8
9
  * Stores the JSS app's context (current route and Sitecore context data).
@@ -14,10 +15,11 @@ export class JssContextServerSideService extends JssContextService {
14
15
  constructor(
15
16
  protected transferState: TransferState,
16
17
  protected layoutService: JssLayoutService,
18
+ protected stateService: JssStateService<JssState>,
17
19
  // this initial state from sitecore is injected by server.bundle for "integrated" mode
18
20
  @Inject('JSS_SERVER_LAYOUT_DATA') private serverToSsrState: JssState
19
21
  ) {
20
- super(transferState, layoutService);
22
+ super(transferState, layoutService, stateService);
21
23
  }
22
24
  changeRoute(_route: string, _language: string): Observable<JssState> {
23
25
  // console.log('Server route change to ' + route);
@@ -34,7 +36,7 @@ export class JssContextServerSideService extends JssContextService {
34
36
  }
35
37
 
36
38
  // read initial state from data injected via server.bundle wrapper
37
- this.state.next(this.serverToSsrState);
39
+ this.stateService.setState(this.serverToSsrState);
38
40
 
39
41
  // place the initial state into TransferState for the client
40
42
  this.transferState.set<JssState>(jssKey, this.serverToSsrState);