create-sitecore-jss 22.2.0-canary.37 → 22.2.0-canary.39

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.
@@ -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,
@@ -4,15 +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 { getGraphQLClientFactoryConfig } from './src/app/lib/graphql-client-factory/config';
11
- import { dictionaryServiceFactory } from './src/app/lib/dictionary-service-factory';
12
- import { layoutServiceFactory } from './src/app/lib/layout-service-factory';
13
8
 
14
9
  export * from './src/main.server';
15
10
 
11
+ export * from './server.exports';
12
+
16
13
  const http = require('http');
17
14
  const https = require('https');
18
15
 
@@ -101,20 +98,4 @@ function parseRouteUrl(url: string) {
101
98
  };
102
99
  }
103
100
 
104
- const apiKey = environment.sitecoreApiKey;
105
- const siteName = environment.sitecoreSiteName;
106
- const defaultLanguage = environment.defaultLanguage;
107
- const getClientFactoryConfig = getGraphQLClientFactoryConfig;
108
-
109
- export {
110
- renderView,
111
- parseRouteUrl,
112
- setUpDefaultAgents,
113
- apiKey,
114
- siteName,
115
- clientFactory,
116
- getClientFactoryConfig,
117
- dictionaryServiceFactory,
118
- layoutServiceFactory,
119
- defaultLanguage,
120
- };
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
+ };
@@ -0,0 +1,28 @@
1
+ import 'dotenv/config';
2
+
3
+ /*
4
+ BOOTSTRAPPING
5
+ The bootstrap process runs before build, and generates TS that needs to be
6
+ included into the build - specifically, the component name to component mapping,
7
+ and the global config module.
8
+ */
9
+
10
+ /*
11
+ PLUGINS GENERATION
12
+ */
13
+ require('./generate-plugins');
14
+
15
+ /*
16
+ CONFIG GENERATION
17
+ */
18
+ require('./generate-config');
19
+
20
+ /*
21
+ COMPONENT FACTORY GENERATION
22
+ */
23
+ require('./generate-component-factory');
24
+
25
+ /*
26
+ METADATA GENERATION
27
+ */
28
+ require('./generate-metadata');
@@ -0,0 +1,25 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { Metadata, getMetadata } from '@sitecore-jss/sitecore-jss-dev-tools';
4
+
5
+ /*
6
+ METADATA GENERATION
7
+ Generates the /src/environments/metadata.json file which contains application
8
+ configuration metadata that is used for Sitecore XM Cloud integration.
9
+ */
10
+ generateMetadata();
11
+
12
+ function generateMetadata(): void {
13
+ const metadata: Metadata = getMetadata();
14
+ writeMetadata(metadata);
15
+ }
16
+
17
+ /**
18
+ * Writes the metadata object to disk.
19
+ * @param {Metadata} metadata metadata to write.
20
+ */
21
+ function writeMetadata(metadata: Metadata): void {
22
+ const filePath = path.resolve('src/environments/metadata.json');
23
+ console.log(`Writing metadata to ${filePath}`);
24
+ fs.writeFileSync(filePath, JSON.stringify(metadata, null, 2), { encoding: 'utf8' });
25
+ }
@@ -0,0 +1,28 @@
1
+ import clientFactory from './src/app/lib/graphql-client-factory';
2
+ import { getGraphQLClientFactoryConfig } from './src/app/lib/graphql-client-factory/config';
3
+ import { dictionaryServiceFactory } from './src/app/lib/dictionary-service-factory';
4
+ import { layoutServiceFactory } from './src/app/lib/layout-service-factory';
5
+ import { environment } from './src/environments/environment';
6
+ import { components } from './src/app/components/app-components.module';
7
+ import metadata from './src/environments/metadata.json';
8
+
9
+ /**
10
+ * Define the required configuration values to be exported from the server.bundle.ts.
11
+ */
12
+
13
+ const apiKey = environment.sitecoreApiKey;
14
+ const siteName = environment.sitecoreSiteName;
15
+ const defaultLanguage = environment.defaultLanguage;
16
+ const getClientFactoryConfig = getGraphQLClientFactoryConfig;
17
+
18
+ export {
19
+ apiKey,
20
+ siteName,
21
+ clientFactory,
22
+ getClientFactoryConfig,
23
+ dictionaryServiceFactory,
24
+ layoutServiceFactory,
25
+ defaultLanguage,
26
+ components,
27
+ metadata,
28
+ };
@@ -20,13 +20,14 @@ class PreviewModePlugin implements Plugin {
20
20
 
21
21
  // If we're in Pages preview (editing) Metadata Edit Mode, prefetch the editing data
22
22
  if (isEditingMetadataPreviewData(context.previewData)) {
23
- const { site, itemId, language, version, variantIds } = context.previewData;
23
+ const { site, itemId, language, version, variantIds, layoutKind } = context.previewData;
24
24
 
25
25
  const data = await graphQLEditingService.fetchEditingData({
26
26
  siteName: site,
27
27
  itemId,
28
28
  language,
29
29
  version,
30
+ layoutKind,
30
31
  });
31
32
 
32
33
  if (!data) {
@@ -1,4 +1,4 @@
1
- import { ProxyConfig, ServerBundle } from '@sitecore-jss/sitecore-jss-proxy';
1
+ import { headlessProxy } from '@sitecore-jss/sitecore-jss-proxy';
2
2
  import fs from 'fs';
3
3
  import { RestDictionaryService } from '@sitecore-jss/sitecore-jss/i18n';
4
4
  import { httpAgentsConfig } from './httpAgents';
@@ -13,7 +13,7 @@ let siteName = process.env.SITECORE_SITE_NAME || appName;
13
13
 
14
14
  const bundlePath = process.env.SITECORE_JSS_SERVER_BUNDLE || `../dist/${appName}/server.bundle`;
15
15
 
16
- const serverBundle = require(bundlePath) as ServerBundle;
16
+ const serverBundle = require(bundlePath) as headlessProxy.ServerBundle;
17
17
 
18
18
  httpAgentsConfig.setUpDefaultAgents(serverBundle);
19
19
 
@@ -33,7 +33,7 @@ const dictionaryService = new RestDictionaryService({
33
33
  /**
34
34
  * @type {ProxyConfig}
35
35
  */
36
- export const config: ProxyConfig = {
36
+ export const config: headlessProxy.ProxyConfig = {
37
37
  /**
38
38
  * The require'd server.bundle.js file from your pre-built JSS app
39
39
  */
@@ -1,4 +1,4 @@
1
- import { ServerBundle } from '@sitecore-jss/sitecore-jss-proxy';
1
+ import { headlessProxy } from '@sitecore-jss/sitecore-jss-proxy';
2
2
  import keepAlive from 'agentkeepalive';
3
3
  import http from 'http';
4
4
  import https from 'https';
@@ -14,7 +14,7 @@ const httpAgent = new keepAlive(keepAliveConfig);
14
14
  const httpsAgent = (new keepAlive.HttpsAgent(keepAliveConfig) as unknown) as https.Agent;
15
15
 
16
16
  interface HttpAgentsConfig {
17
- setUpDefaultAgents: (serverBundle: ServerBundle) => void;
17
+ setUpDefaultAgents: (serverBundle: headlessProxy.ServerBundle) => void;
18
18
  getAgent: (url: string) => http.Agent | https.Agent;
19
19
  }
20
20
 
@@ -1,7 +1,7 @@
1
1
  import express from 'express';
2
2
  import compression from 'compression';
3
3
  import 'dotenv/config';
4
- import scProxy from '@sitecore-jss/sitecore-jss-proxy';
4
+ import { headlessProxy } from '@sitecore-jss/sitecore-jss-proxy';
5
5
  import { config } from './config';
6
6
  //import { cacheMiddleware } from './cacheMiddleware';
7
7
 
@@ -42,7 +42,14 @@ server.use((req, _res, next) => {
42
42
  });
43
43
 
44
44
  // For any other requests, we render app routes server-side and return them
45
- server.use('*', scProxy(config.serverBundle.renderView, config, config.serverBundle.parseRouteUrl));
45
+ server.use(
46
+ '*',
47
+ headlessProxy.middleware(
48
+ config.serverBundle.renderView,
49
+ config,
50
+ config.serverBundle.parseRouteUrl
51
+ )
52
+ );
46
53
 
47
54
  server.listen(port, () => {
48
55
  console.log(`server listening on port ${port}!`);
@@ -1,3 +1,9 @@
1
+ # To secure the Sitecore editor endpoint exposed by your proxy app
2
+ # (`/api/editing/render` by default), a secret token is used.
3
+ # The environment variable is used by `editingRouter`
4
+ # We recommend an alphanumeric value of at least 16 characters.
5
+ JSS_EDITING_SECRET=
6
+
1
7
  # Your proxy port (default: 3001)
2
8
  PROXY_PORT=
3
9
 
@@ -10,6 +10,7 @@
10
10
  "start": "ts-node ./src/index.ts"
11
11
  },
12
12
  "dependencies": {
13
+ "@sitecore-jss/sitecore-jss-proxy": "~22.2.0-canary",
13
14
  "compression": "^1.7.4",
14
15
  "express": "^4.18.2",
15
16
  "dotenv": "^16.0.3",
@@ -3,6 +3,7 @@ import express, { Response } from 'express';
3
3
  import compression from 'compression';
4
4
  import { createProxyMiddleware } from 'http-proxy-middleware';
5
5
  import { debug } from '@sitecore-jss/sitecore-jss';
6
+ import { editingRouter } from '@sitecore-jss/sitecore-jss-proxy';
6
7
  import { config } from './config';
7
8
 
8
9
  const server = express();
@@ -26,6 +27,8 @@ const requiredProperties = [
26
27
  'defaultLanguage',
27
28
  'layoutServiceFactory',
28
29
  'dictionaryServiceFactory',
30
+ 'components',
31
+ 'metadata',
29
32
  ];
30
33
 
31
34
  const missingProperties = requiredProperties.filter((property) => !config.serverBundle[property]);
@@ -46,7 +49,7 @@ const graphQLEndpoint = (() => {
46
49
 
47
50
  try {
48
51
  const graphQLEndpoint = new URL(clientFactoryConfig.endpoint);
49
- // Browser request path to the proxy. Includes only the pathname.
52
+ // Browser request path to the proxy. Includes only the pathname.
50
53
  const pathname = graphQLEndpoint.pathname;
51
54
  // Target URL for the proxy. Can't include the query string.
52
55
  const target = `${graphQLEndpoint.protocol}//${graphQLEndpoint.hostname}${pathname}`;
@@ -125,6 +128,19 @@ server.use(
125
128
  })
126
129
  );
127
130
 
131
+ /**
132
+ * Proxy editing requests through the editing router
133
+ */
134
+ server.use(
135
+ '/api/editing',
136
+ editingRouter({
137
+ config: {
138
+ components: config.serverBundle.components,
139
+ metadata: config.serverBundle.metadata,
140
+ },
141
+ })
142
+ );
143
+
128
144
  server.use(async (req, res) => {
129
145
  debug.proxy(`performing SSR for ${req.originalUrl}`);
130
146
 
@@ -3,44 +3,9 @@ import {
3
3
  GraphQLRequestClientFactoryConfig,
4
4
  } from '@sitecore-jss/sitecore-jss';
5
5
  import { DictionaryService } from '@sitecore-jss/sitecore-jss/i18n';
6
- import { LayoutService, LayoutServiceData } from '@sitecore-jss/sitecore-jss/layout';
7
-
8
- interface ServerResponse {
9
- /**
10
- * The rendered HTML to return to the client
11
- */
12
- html: string;
13
- /**
14
- * Set the HTTP status code. If not set, the status code returned from Layout Service is returned.
15
- */
16
- status?: number;
17
- /**
18
- * Sets a redirect URL, causing the reply to send a HTTP redirect instead of the HTML content.
19
- * Note: when using this you must set the status code to 301 or 302.
20
- */
21
- redirect?: string;
22
- }
23
-
24
- declare type AppRenderer = (
25
- callback: (error: Error | null, result: ServerResponse | null) => void,
26
- path: string,
27
- /**
28
- * Data returned by Layout Service. If the route does not exist, null.
29
- */
30
- layoutData: LayoutServiceData,
31
- viewBag: {
32
- [key: string]: unknown;
33
- dictionary: { [key: string]: string };
34
- }
35
- ) => void;
36
-
37
- declare type RouteUrlParser = (
38
- url: string
39
- ) => {
40
- sitecoreRoute?: string;
41
- lang?: string;
42
- qsParams?: string;
43
- };
6
+ import { Metadata } from '@sitecore-jss/sitecore-jss/utils';
7
+ import { LayoutService } from '@sitecore-jss/sitecore-jss/layout';
8
+ import { AppRenderer, RouteUrlParser } from '@sitecore-jss/sitecore-jss-proxy';
44
9
 
45
10
  export interface ServerBundle {
46
11
  [key: string]: unknown;
@@ -52,6 +17,8 @@ export interface ServerBundle {
52
17
  defaultLanguage: string;
53
18
  layoutServiceFactory: { create: () => LayoutService };
54
19
  dictionaryServiceFactory: { create: () => DictionaryService };
20
+ components: string[] | Map<string, unknown>;
21
+ metadata: Metadata;
55
22
  }
56
23
 
57
24
  export interface Config {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-sitecore-jss",
3
- "version": "22.2.0-canary.37",
3
+ "version": "22.2.0-canary.39",
4
4
  "description": "Sitecore JSS initializer",
5
5
  "bin": "./dist/index.js",
6
6
  "scripts": {
@@ -63,5 +63,5 @@
63
63
  "ts-node": "^10.9.1",
64
64
  "typescript": "~4.9.5"
65
65
  },
66
- "gitHead": "2f18bc17c4728742b8ba81f1df2c237d4102d14c"
66
+ "gitHead": "b4f4b36dd7b9b0aadabfeca4c8886ca3db8cfec5"
67
67
  }