create-sitecore-jss 22.2.0-canary.6 → 22.2.0-canary.61
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/dist/bin.js +17 -42
- package/dist/common/index.js +3 -1
- package/dist/common/processes/next.js +6 -3
- package/dist/common/processes/transform.js +13 -13
- package/dist/common/prompts/base.js +0 -25
- package/dist/common/prompts/proxy.js +35 -0
- package/dist/common/prompts/sxp.js +34 -0
- package/dist/common/utils/helpers.js +37 -2
- package/dist/init-runner.js +4 -3
- package/dist/initializers/angular/index.js +0 -3
- package/dist/initializers/angular/prompts.js +6 -6
- package/dist/initializers/angular-sxp/index.js +7 -1
- package/dist/initializers/angular-xmcloud/index.js +27 -3
- package/dist/initializers/nextjs/prompts.js +2 -0
- package/dist/initializers/node-xmcloud-proxy/index.js +2 -1
- package/dist/initializers/react/prompts.js +1 -1
- package/dist/initializers/react-native/prompts.js +1 -0
- package/dist/initializers/vue/prompts.js +1 -1
- package/dist/templates/angular/.env +4 -5
- package/dist/templates/angular/.eslintrc +1 -0
- package/dist/templates/angular/gitignore +5 -0
- package/dist/templates/angular/package.json +0 -2
- package/dist/templates/angular/scripts/config/plugins/fallback.ts +0 -1
- package/dist/templates/angular/scripts/generate-component-factory.ts +8 -0
- package/dist/templates/angular/scripts/generate-config.ts +25 -6
- package/dist/templates/angular/scripts/update-graphql-fragment-data.ts +21 -30
- package/dist/templates/angular/server.bundle.ts +3 -23
- package/dist/templates/angular/server.exports.ts +13 -0
- package/dist/templates/angular/src/app/JssState.ts +2 -9
- package/dist/templates/angular/src/app/app.module.ts +5 -4
- package/dist/templates/angular/src/app/app.server.module.ts +9 -6
- package/dist/templates/angular/src/app/i18n/jss-translation-client-loader.service.ts +15 -7
- package/dist/templates/angular/src/app/i18n/jss-translation-server-loader.service.ts +14 -2
- package/dist/templates/angular/src/app/jss-context.server-side.service.ts +4 -2
- package/dist/templates/angular/src/app/jss-context.service.ts +14 -11
- package/dist/templates/angular/src/app/jss-graphql.service.ts +7 -7
- package/dist/templates/angular/src/app/layout/jss-layout.service.ts +2 -2
- package/dist/templates/angular/src/app/lib/dictionary-service-factory.ts +4 -1
- package/dist/templates/angular/src/app/lib/graphql-client-factory/config.ts +21 -0
- package/dist/templates/angular/src/app/lib/graphql-client-factory/index.ts +16 -0
- package/dist/templates/angular/src/app/lib/layout-service-factory.ts +1 -1
- package/dist/templates/angular/src/app/routing/layout/layout.component.ts +10 -9
- package/dist/templates/angular/src/environments/gitignore +2 -1
- package/dist/templates/angular-sxp/.env +2 -0
- package/dist/templates/angular-sxp/scripts/config/plugins/disconnected.ts +4 -2
- package/dist/templates/angular-sxp/src/app/components/graph-ql-layout/graph-ql-layout.component.ts +1 -1
- package/dist/templates/angular-xmcloud/.env +8 -2
- package/dist/templates/angular-xmcloud/angular.json +0 -1
- package/dist/templates/angular-xmcloud/scripts/bootstrap.ts +28 -0
- package/dist/templates/angular-xmcloud/scripts/config/plugins/xmcloud.ts +16 -0
- package/dist/templates/angular-xmcloud/scripts/generate-metadata.ts +25 -0
- package/dist/templates/angular-xmcloud/server.exports.ts +24 -0
- package/dist/templates/angular-xmcloud/src/app/components/app-components.shared.module.ts +21 -0
- package/dist/templates/angular-xmcloud/src/app/components/column-splitter/column-splitter.component.html +5 -0
- package/dist/templates/angular-xmcloud/src/app/components/column-splitter/column-splitter.component.ts +40 -0
- package/dist/templates/angular-xmcloud/src/app/components/container/container.component.html +14 -0
- package/dist/templates/angular-xmcloud/src/app/components/container/container.component.ts +30 -0
- package/dist/templates/angular-xmcloud/src/app/components/image/image.component.html +36 -0
- package/dist/templates/angular-xmcloud/src/app/components/image/image.component.ts +67 -0
- package/dist/templates/angular-xmcloud/src/app/components/link-list/link-list.component.html +15 -0
- package/dist/templates/angular-xmcloud/src/app/components/link-list/link-list.component.ts +41 -0
- package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation-item.component.html +23 -0
- package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation-item.component.ts +65 -0
- package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation.component.html +21 -0
- package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation.component.ts +49 -0
- package/dist/templates/angular-xmcloud/src/app/components/page-content/page-content.component.html +5 -0
- package/dist/templates/angular-xmcloud/src/app/components/page-content/page-content.component.ts +39 -0
- package/dist/templates/angular-xmcloud/src/app/components/partial-design-dynamic-placeholder/partial-design-dynamic-placeholder.component.html +1 -0
- package/dist/templates/angular-xmcloud/src/app/components/partial-design-dynamic-placeholder/partial-design-dynamic-placeholder.component.ts +15 -0
- package/dist/templates/angular-xmcloud/src/app/components/promo/promo.component.html +21 -0
- package/dist/templates/angular-xmcloud/src/app/components/promo/promo.component.ts +13 -0
- package/dist/templates/angular-xmcloud/src/app/components/richtext/richtext.component.html +7 -12
- package/dist/templates/angular-xmcloud/src/app/components/richtext/richtext.component.ts +6 -1
- package/dist/templates/angular-xmcloud/src/app/components/row-splitter/row-splitter.component.html +11 -0
- package/dist/templates/angular-xmcloud/src/app/components/row-splitter/row-splitter.component.ts +35 -0
- package/dist/templates/angular-xmcloud/src/app/components/sxa.component.ts +4 -4
- package/dist/templates/angular-xmcloud/src/app/components/title/title.component.html +10 -0
- package/dist/templates/angular-xmcloud/src/app/components/title/title.component.ts +56 -0
- package/dist/templates/angular-xmcloud/src/app/jss-link.service.ts +55 -0
- package/dist/templates/angular-xmcloud/src/app/lib/config.ts +2 -0
- package/dist/templates/angular-xmcloud/src/app/lib/graphql-client-factory/config.ts +58 -0
- package/dist/templates/angular-xmcloud/src/app/routing/layout/layout.component.html +38 -0
- package/dist/templates/angular-xmcloud/src/app/routing/layout/layout.component.ts +104 -0
- package/dist/templates/angular-xmcloud/src/app/routing/scripts/scripts.component.html +3 -0
- package/dist/templates/angular-xmcloud/src/app/routing/scripts/scripts.module.ts +10 -0
- package/dist/templates/angular-xmcloud/src/assets/styles/basic/_header.scss +3 -1
- package/dist/templates/angular-xmcloud/src/assets/styles/main.scss +10 -0
- package/dist/templates/angular-xmcloud/src/assets/styles/sass/components/_component-image.scss +1 -1
- package/dist/templates/nextjs/package.json +1 -1
- package/dist/templates/nextjs/scripts/config/plugins/fallback.ts +0 -1
- package/dist/templates/nextjs/scripts/generate-config.ts +8 -1
- package/dist/templates/nextjs/src/lib/page-props-factory/plugins/component-props.ts +2 -1
- package/dist/templates/nextjs-styleguide/scripts/config/plugins/disconnected.ts +1 -0
- package/dist/templates/nextjs-sxa/src/assets/sass/components/_component-image.scss +1 -1
- package/dist/templates/nextjs-sxa/src/components/Container.tsx +6 -14
- package/dist/templates/nextjs-xmcloud/src/lib/page-props-factory/plugins/component-themes.ts +2 -1
- package/dist/templates/nextjs-xmcloud/src/lib/page-props-factory/plugins/preview-mode.ts +2 -1
- package/dist/templates/node-headless-ssr-experience-edge/gitignore +19 -0
- package/dist/templates/node-headless-ssr-proxy/gitignore +19 -0
- package/dist/templates/node-headless-ssr-proxy/src/config.ts +3 -3
- package/dist/templates/node-headless-ssr-proxy/src/httpAgents.ts +2 -2
- package/dist/templates/node-headless-ssr-proxy/src/index.ts +9 -2
- package/dist/templates/node-xmcloud-proxy/.env +7 -1
- package/dist/templates/node-xmcloud-proxy/README.md +1 -1
- package/dist/templates/node-xmcloud-proxy/gitignore +33 -0
- package/dist/templates/node-xmcloud-proxy/package.json +3 -2
- package/dist/templates/node-xmcloud-proxy/src/config.ts +9 -3
- package/dist/templates/node-xmcloud-proxy/src/index.ts +54 -5
- package/dist/templates/node-xmcloud-proxy/src/types.ts +10 -42
- package/dist/templates/react/scripts/generate-config.js +10 -3
- package/dist/templates/vue/scripts/generate-config.js +5 -0
- package/package.json +2 -2
- package/dist/templates/angular/src/app/lib/graphql-client-factory.ts +0 -28
- package/dist/templates/angular-xmcloud/src/app/lib/graphql-client-factory.ts +0 -44
|
@@ -79,12 +79,14 @@ function generateComponentFactory() {
|
|
|
79
79
|
const registrations: string[] = [];
|
|
80
80
|
const lazyRegistrations: string[] = [];
|
|
81
81
|
const declarations: string[] = [];
|
|
82
|
+
const components: string[] = [];
|
|
82
83
|
|
|
83
84
|
packages.forEach((p) => {
|
|
84
85
|
const variables = p.components
|
|
85
86
|
.map((c) => {
|
|
86
87
|
registrations.push(`{ name: '${c.componentName}', type: ${c.moduleName} },`);
|
|
87
88
|
declarations.push(`${c.moduleName},`);
|
|
89
|
+
components.push(c.componentName);
|
|
88
90
|
|
|
89
91
|
return c.moduleName;
|
|
90
92
|
})
|
|
@@ -118,6 +120,8 @@ function generateComponentFactory() {
|
|
|
118
120
|
const componentName = componentClassMatch[1];
|
|
119
121
|
const importVarName = `${componentName}Component`;
|
|
120
122
|
|
|
123
|
+
components.push(componentName);
|
|
124
|
+
|
|
121
125
|
// check for lazy loading needs
|
|
122
126
|
const moduleFilePath = path.join(componentRootPath, componentFolder, `${componentFolder}.module.ts`);
|
|
123
127
|
const isLazyLoaded = fs.existsSync(moduleFilePath);
|
|
@@ -144,6 +148,10 @@ import { JssModule } from '@sitecore-jss/sitecore-jss-angular';
|
|
|
144
148
|
import { AppComponentsSharedModule } from './app-components.shared.module';
|
|
145
149
|
${imports.join('\n')}
|
|
146
150
|
|
|
151
|
+
export const components = [
|
|
152
|
+
${components.map((c) => `'${c}'`).join(',\n ')}
|
|
153
|
+
];
|
|
154
|
+
|
|
147
155
|
@NgModule({
|
|
148
156
|
imports: [
|
|
149
157
|
AppComponentsSharedModule,
|
|
@@ -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
|
-
|
|
27
|
-
generateConfig('src/environments/environment.
|
|
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
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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;`;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as fetch from 'isomorphic-fetch';
|
|
2
1
|
import * as fs from 'fs';
|
|
3
|
-
import
|
|
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
|
-
|
|
12
|
+
import './generate-config';
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
const clientFactoryConfig = getGraphQLClientFactoryConfig();
|
|
15
15
|
|
|
16
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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.
|
|
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.
|
|
46
|
+
filteredResult.__schema.types = filteredData;
|
|
56
47
|
|
|
57
48
|
fs.writeFile(
|
|
58
49
|
'./src/graphql-fragment-types.ts',
|
|
59
|
-
`export default ${JSON.stringify(filteredResult
|
|
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
|
-
|
|
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
|
|
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
|
|
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: () =>
|
|
24
|
-
|
|
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: (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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,16 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Injectable, TransferState } from '@angular/core';
|
|
2
2
|
import { TranslateLoader } from '@ngx-translate/core';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
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:
|
|
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:
|
|
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.
|
|
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);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Injectable, TransferState, makeStateKey } from '@angular/core';
|
|
2
|
-
import { LayoutServiceData } from '@sitecore-jss/sitecore-jss-angular';
|
|
2
|
+
import { LayoutServiceData, JssStateService } from '@sitecore-jss/sitecore-jss-angular';
|
|
3
3
|
import { map, shareReplay, catchError } from 'rxjs/operators';
|
|
4
|
-
import { Observable, of as observableOf
|
|
5
|
-
import { JssState } from './JssState';
|
|
4
|
+
import { Observable, of as observableOf } from 'rxjs';
|
|
6
5
|
import { JssLayoutService, LayoutServiceError } from './layout/jss-layout.service';
|
|
6
|
+
import { JssState } from './JssState';
|
|
7
7
|
|
|
8
8
|
export const jssKey = makeStateKey<JssState>('jss');
|
|
9
9
|
|
|
@@ -16,14 +16,17 @@ export const jssKey = makeStateKey<JssState>('jss');
|
|
|
16
16
|
export class JssContextService {
|
|
17
17
|
// components can subscribe to this (or use getValue()) to get access to latest data from Layout Service,
|
|
18
18
|
// as well as current language and server route
|
|
19
|
-
state
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
get state() {
|
|
20
|
+
return this.stateService.state;
|
|
21
|
+
}
|
|
22
|
+
get stateValue() {
|
|
23
|
+
return this.stateService.stateValue;
|
|
24
|
+
}
|
|
25
|
+
constructor(protected transferState: TransferState, protected layoutService: JssLayoutService, protected stateService: JssStateService<JssState>) {
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
changeLanguage(language: string) {
|
|
26
|
-
this.
|
|
29
|
+
this.stateService.setState({ ...this.stateService.stateValue, language });
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
// primarily invoked by JssRouteResolver on URL/route change
|
|
@@ -33,11 +36,11 @@ export class JssContextService {
|
|
|
33
36
|
if (foundInitialState) {
|
|
34
37
|
const jssState = this.transferState.get<JssState>(jssKey, null);
|
|
35
38
|
this.transferState.remove(jssKey);
|
|
36
|
-
this.
|
|
39
|
+
this.stateService.setState(jssState);
|
|
37
40
|
return observableOf(jssState);
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
const appLanguage = this.
|
|
43
|
+
const appLanguage = this.stateService.stateValue.language || language;
|
|
41
44
|
|
|
42
45
|
const jssState$ = this.layoutService.getRouteData(route, appLanguage).pipe(
|
|
43
46
|
map((routeData) => {
|
|
@@ -61,7 +64,7 @@ export class JssContextService {
|
|
|
61
64
|
|
|
62
65
|
// subscribe to it ourselves so we can maintain current state
|
|
63
66
|
jssState$.subscribe((jssState) => {
|
|
64
|
-
this.
|
|
67
|
+
this.stateService.setState(jssState);
|
|
65
68
|
});
|
|
66
69
|
|
|
67
70
|
return jssState$;
|
|
@@ -43,7 +43,7 @@ export class JssGraphQLService {
|
|
|
43
43
|
) {
|
|
44
44
|
this.isEditingOrPreviewingAndSsr =
|
|
45
45
|
isPlatformServer(this.platformId) &&
|
|
46
|
-
this.sitecoreContext.
|
|
46
|
+
this.sitecoreContext.stateValue.sitecore.context.pageState !== 'normal';
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
private static extractVariableNames(query: DocumentNode) {
|
|
@@ -127,19 +127,19 @@ export class JssGraphQLService {
|
|
|
127
127
|
|
|
128
128
|
if (
|
|
129
129
|
usedVariables.contextItem &&
|
|
130
|
-
this.sitecoreContext.
|
|
131
|
-
this.sitecoreContext.
|
|
132
|
-
this.sitecoreContext.
|
|
130
|
+
this.sitecoreContext.stateValue.sitecore &&
|
|
131
|
+
this.sitecoreContext.stateValue.sitecore.route &&
|
|
132
|
+
this.sitecoreContext.stateValue.sitecore.route.itemId
|
|
133
133
|
) {
|
|
134
|
-
(variables as EmptyObject).contextItem = this.sitecoreContext.
|
|
134
|
+
(variables as EmptyObject).contextItem = this.sitecoreContext.stateValue.sitecore.route.itemId;
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
// pass language as a variable to the query, if language exists as a variable and in sitecoreContext
|
|
138
138
|
if (
|
|
139
139
|
usedVariables.language &&
|
|
140
|
-
this.sitecoreContext.
|
|
140
|
+
this.sitecoreContext.stateValue.language
|
|
141
141
|
) {
|
|
142
|
-
(variables as EmptyObject).language = this.sitecoreContext.
|
|
142
|
+
(variables as EmptyObject).language = this.sitecoreContext.stateValue.language;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
return variables;
|
|
@@ -7,14 +7,14 @@ import { from as fromPromise, Observable, throwError as observableThrow } from '
|
|
|
7
7
|
import { catchError, map } from 'rxjs/operators';
|
|
8
8
|
import { layoutServiceFactory } from '../lib/layout-service-factory';
|
|
9
9
|
|
|
10
|
-
const layoutServiceInstance = layoutServiceFactory.create();
|
|
11
|
-
|
|
12
10
|
export class LayoutServiceError {
|
|
13
11
|
status: number;
|
|
14
12
|
statusText: string;
|
|
15
13
|
data?: { sitecore?: LayoutServiceContextData };
|
|
16
14
|
}
|
|
17
15
|
|
|
16
|
+
const layoutServiceInstance = layoutServiceFactory.create();
|
|
17
|
+
|
|
18
18
|
@Injectable()
|
|
19
19
|
export class JssLayoutService {
|
|
20
20
|
getRouteData(
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
<% } -%>
|
|
8
8
|
} from '@sitecore-jss/sitecore-jss-angular';
|
|
9
9
|
import { environment as env } from '../../environments/environment';
|
|
10
|
-
import
|
|
10
|
+
import clientFactory from './graphql-client-factory';
|
|
11
11
|
|
|
12
12
|
export class DictionaryServiceFactory {
|
|
13
13
|
create(): DictionaryService {
|
|
@@ -24,6 +24,9 @@ export class DictionaryServiceFactory {
|
|
|
24
24
|
new GraphQLDictionaryService({
|
|
25
25
|
clientFactory,
|
|
26
26
|
siteName: env.sitecoreSiteName,
|
|
27
|
+
<% if (locals.xmcloud) { -%>
|
|
28
|
+
useSiteQuery: true,
|
|
29
|
+
<% } -%>
|
|
27
30
|
/*
|
|
28
31
|
The Dictionary Service needs a root item ID in order to fetch dictionary phrases for the current
|
|
29
32
|
app. If your Sitecore instance only has 1 JSS App, you can specify the root item ID here;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { GraphQLRequestClientFactoryConfig } from '@sitecore-jss/sitecore-jss-angular/cjs';
|
|
2
|
+
import { environment as env } from '../../../environments/environment';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Gets the configuration for the GraphQLRequestClientFactory
|
|
6
|
+
* @returns GraphQLRequestClientFactoryConfig
|
|
7
|
+
*/
|
|
8
|
+
export const getGraphQLClientFactoryConfig = () => {
|
|
9
|
+
let clientConfig: GraphQLRequestClientFactoryConfig;
|
|
10
|
+
|
|
11
|
+
if (env.graphQLEndpoint && env.sitecoreApiKey) {
|
|
12
|
+
clientConfig = {
|
|
13
|
+
endpoint: env.graphQLEndpoint,
|
|
14
|
+
apiKey: env.sitecoreApiKey,
|
|
15
|
+
};
|
|
16
|
+
} else {
|
|
17
|
+
throw new Error('Please configure your graphQLEndpoint and sitecoreApiKey.');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return clientConfig;
|
|
21
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { GraphQLRequestClient } from '@sitecore-jss/sitecore-jss-angular/cjs';
|
|
2
|
+
import { getGraphQLClientFactoryConfig } from './config';
|
|
3
|
+
|
|
4
|
+
// The GraphQLRequestClientFactory serves as the central hub for executing GraphQL requests within the application
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a new GraphQLRequestClientFactory instance
|
|
8
|
+
* @returns GraphQLRequestClientFactory instance
|
|
9
|
+
*/
|
|
10
|
+
const createGraphQLClientFactory = () => {
|
|
11
|
+
const clientConfig = getGraphQLClientFactoryConfig();
|
|
12
|
+
|
|
13
|
+
return GraphQLRequestClient.createClientFactory(clientConfig);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default createGraphQLClientFactory();
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
<% } -%>
|
|
8
8
|
} from '@sitecore-jss/sitecore-jss-angular';
|
|
9
9
|
import { environment } from '../../environments/environment';
|
|
10
|
-
import
|
|
10
|
+
import clientFactory from './graphql-client-factory';
|
|
11
11
|
|
|
12
12
|
export class LayoutServiceFactory {
|
|
13
13
|
create(): LayoutService {
|
|
@@ -9,12 +9,12 @@ import { JssMetaService } from '../../jss-meta.service';
|
|
|
9
9
|
enum LayoutState {
|
|
10
10
|
Layout,
|
|
11
11
|
NotFound,
|
|
12
|
-
Error
|
|
12
|
+
Error,
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
interface RouteFields {
|
|
16
16
|
[name: string]: unknown;
|
|
17
|
-
pageTitle
|
|
17
|
+
pageTitle?: Field<string>;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
@Component({
|
|
@@ -28,14 +28,11 @@ export class LayoutComponent implements OnInit, OnDestroy {
|
|
|
28
28
|
subscription: Subscription;
|
|
29
29
|
errorContextData: LayoutServiceContextData;
|
|
30
30
|
|
|
31
|
-
constructor(
|
|
32
|
-
private activatedRoute: ActivatedRoute,
|
|
33
|
-
private readonly meta: JssMetaService,
|
|
34
|
-
) { }
|
|
31
|
+
constructor(private activatedRoute: ActivatedRoute, private readonly meta: JssMetaService) {}
|
|
35
32
|
|
|
36
33
|
ngOnInit() {
|
|
37
34
|
// route data is populated by the JssRouteResolver
|
|
38
|
-
this.subscription = this.activatedRoute.data.subscribe((data: { jssState: JssState
|
|
35
|
+
this.subscription = this.activatedRoute.data.subscribe((data: { jssState: JssState }) => {
|
|
39
36
|
if (!data.jssState) {
|
|
40
37
|
this.state = LayoutState.NotFound;
|
|
41
38
|
return;
|
|
@@ -48,13 +45,17 @@ export class LayoutComponent implements OnInit, OnDestroy {
|
|
|
48
45
|
}
|
|
49
46
|
|
|
50
47
|
if (data.jssState.routeFetchError) {
|
|
51
|
-
if (
|
|
48
|
+
if (
|
|
49
|
+
data.jssState.routeFetchError.status >= 400 &&
|
|
50
|
+
data.jssState.routeFetchError.status < 500
|
|
51
|
+
) {
|
|
52
52
|
this.state = LayoutState.NotFound;
|
|
53
53
|
} else {
|
|
54
54
|
this.state = LayoutState.Error;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
this.errorContextData =
|
|
57
|
+
this.errorContextData =
|
|
58
|
+
data.jssState.routeFetchError.data && data.jssState.routeFetchError.data.sitecore;
|
|
58
59
|
}
|
|
59
60
|
});
|
|
60
61
|
}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
*
|
|
2
|
+
!.gitignore
|