@salesforce/pwa-kit-create-app 3.5.0-alpha.0 → 3.5.0-alpha.1

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.
@@ -0,0 +1,131 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ import React from 'react'
8
+ import PropTypes from 'prop-types'
9
+ import {ChakraProvider} from '@salesforce/retail-react-app/app/components/shared/ui'
10
+
11
+ // Removes focus for non-keyboard interactions for the whole application
12
+ import 'focus-visible/dist/focus-visible'
13
+
14
+ import theme from '@salesforce/retail-react-app/app/theme'
15
+ import {MultiSiteProvider} from '@salesforce/retail-react-app/app/contexts'
16
+ import {
17
+ resolveSiteFromUrl,
18
+ resolveLocaleFromUrl
19
+ } from '@salesforce/retail-react-app/app/utils/site-utils'
20
+ import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config'
21
+ import {createUrlTemplate} from '@salesforce/retail-react-app/app/utils/url'
22
+
23
+ import {CommerceApiProvider} from '@salesforce/commerce-sdk-react'
24
+ import {withReactQuery} from '@salesforce/pwa-kit-react-sdk/ssr/universal/components/with-react-query'
25
+ import {useCorrelationId} from '@salesforce/pwa-kit-react-sdk/ssr/universal/hooks'
26
+ import {getAppOrigin} from '@salesforce/pwa-kit-react-sdk/utils/url'
27
+ import {ReactQueryDevtools} from '@tanstack/react-query-devtools'
28
+
29
+ /**
30
+ * Use the AppConfig component to inject extra arguments into the getProps
31
+ * methods for all Route Components in the app – typically you'd want to do this
32
+ * to inject a connector instance that can be used in all Pages.
33
+ *
34
+ * You can also use the AppConfig to configure a state-management library such
35
+ * as Redux, or Mobx, if you like.
36
+ */
37
+ const AppConfig = ({children, locals = {}}) => {
38
+ const {correlationId} = useCorrelationId()
39
+ const headers = {
40
+ 'correlation-id': correlationId
41
+ }
42
+
43
+ const commerceApiConfig = locals.appConfig.commerceAPI
44
+
45
+ const appOrigin = getAppOrigin()
46
+
47
+ return (
48
+ <CommerceApiProvider
49
+ shortCode={commerceApiConfig.parameters.shortCode}
50
+ clientId={commerceApiConfig.parameters.clientId}
51
+ organizationId={commerceApiConfig.parameters.organizationId}
52
+ siteId={locals.site?.id}
53
+ locale={locals.locale?.id}
54
+ currency={locals.locale?.preferredCurrency}
55
+ redirectURI={`${appOrigin}/callback`}
56
+ proxy={`${appOrigin}${commerceApiConfig.proxyPath}`}
57
+ headers={headers}
58
+ OCAPISessionsURL={`${appOrigin}/mobify/proxy/ocapi/s/${locals.site?.id}/dw/shop/v22_8/sessions`}
59
+ {{#if answers.project.commerce.isSlasPrivate}}
60
+ // Set 'enablePWAKitPrivateClient' to true use SLAS private client login flows.
61
+ // Make sure to also enable useSLASPrivateClient in ssr.js when enabling this setting.
62
+ enablePWAKitPrivateClient={true}
63
+ {{/if}}
64
+ >
65
+ <MultiSiteProvider site={locals.site} locale={locals.locale} buildUrl={locals.buildUrl}>
66
+ <ChakraProvider theme={theme}>{children}</ChakraProvider>
67
+ </MultiSiteProvider>
68
+ <ReactQueryDevtools />
69
+ </CommerceApiProvider>
70
+ )
71
+ }
72
+
73
+ AppConfig.restore = (locals = {}) => {
74
+ const path =
75
+ typeof window === 'undefined'
76
+ ? locals.originalUrl
77
+ : `${window.location.pathname}${window.location.search}`
78
+ const site = resolveSiteFromUrl(path)
79
+ const locale = resolveLocaleFromUrl(path)
80
+
81
+ const {app: appConfig} = getConfig()
82
+ const apiConfig = {
83
+ ...appConfig.commerceAPI,
84
+ einsteinConfig: appConfig.einsteinAPI
85
+ }
86
+
87
+ apiConfig.parameters.siteId = site.id
88
+
89
+ locals.buildUrl = createUrlTemplate(appConfig, site.alias || site.id, locale.id)
90
+ locals.site = site
91
+ locals.locale = locale
92
+ locals.appConfig = appConfig
93
+ }
94
+
95
+ AppConfig.freeze = () => undefined
96
+
97
+ AppConfig.extraGetPropsArgs = (locals = {}) => {
98
+ return {
99
+ buildUrl: locals.buildUrl,
100
+ site: locals.site,
101
+ locale: locals.locale
102
+ }
103
+ }
104
+
105
+ AppConfig.propTypes = {
106
+ children: PropTypes.node,
107
+ locals: PropTypes.object
108
+ }
109
+
110
+ const isServerSide = typeof window === 'undefined'
111
+
112
+ // Recommended settings for PWA-Kit usages.
113
+ // NOTE: they will be applied on both server and client side.
114
+ // retry is always disabled on server side regardless of the value from the options
115
+ const options = {
116
+ queryClientConfig: {
117
+ defaultOptions: {
118
+ queries: {
119
+ retry: false,
120
+ refetchOnWindowFocus: false,
121
+ staleTime: 10 * 1000,
122
+ ...(isServerSide ? {retryOnMount: false} : {})
123
+ },
124
+ mutations: {
125
+ retry: false
126
+ }
127
+ }
128
+ }
129
+ }
130
+
131
+ export default withReactQuery(AppConfig, options)
@@ -29,7 +29,14 @@ const options = {
29
29
  // The protocol on which the development Express app listens.
30
30
  // Note that http://localhost is treated as a secure context for development,
31
31
  // except by Safari.
32
- protocol: 'http'
32
+ protocol: 'http',
33
+
34
+ // Option for whether to set up a special endpoint for handling
35
+ // private SLAS clients
36
+ // Set this to false if using a SLAS public client
37
+ // When setting this to true, make sure to also set the PWA_KIT_SLAS_CLIENT_SECRET
38
+ // environment variable as this endpoint will return HTTP 501 if it is not set
39
+ useSLASPrivateClient: {{answers.project.commerce.isSlasPrivate}}
33
40
  }
34
41
 
35
42
  const runtime = getRuntime()
@@ -0,0 +1,131 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ import React from 'react'
8
+ import PropTypes from 'prop-types'
9
+ import {ChakraProvider} from '@salesforce/retail-react-app/app/components/shared/ui'
10
+
11
+ // Removes focus for non-keyboard interactions for the whole application
12
+ import 'focus-visible/dist/focus-visible'
13
+
14
+ import theme from '@salesforce/retail-react-app/app/theme'
15
+ import {MultiSiteProvider} from '@salesforce/retail-react-app/app/contexts'
16
+ import {
17
+ resolveSiteFromUrl,
18
+ resolveLocaleFromUrl
19
+ } from '@salesforce/retail-react-app/app/utils/site-utils'
20
+ import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config'
21
+ import {createUrlTemplate} from '@salesforce/retail-react-app/app/utils/url'
22
+
23
+ import {CommerceApiProvider} from '@salesforce/commerce-sdk-react'
24
+ import {withReactQuery} from '@salesforce/pwa-kit-react-sdk/ssr/universal/components/with-react-query'
25
+ import {useCorrelationId} from '@salesforce/pwa-kit-react-sdk/ssr/universal/hooks'
26
+ import {getAppOrigin} from '@salesforce/pwa-kit-react-sdk/utils/url'
27
+ import {ReactQueryDevtools} from '@tanstack/react-query-devtools'
28
+
29
+ /**
30
+ * Use the AppConfig component to inject extra arguments into the getProps
31
+ * methods for all Route Components in the app – typically you'd want to do this
32
+ * to inject a connector instance that can be used in all Pages.
33
+ *
34
+ * You can also use the AppConfig to configure a state-management library such
35
+ * as Redux, or Mobx, if you like.
36
+ */
37
+ const AppConfig = ({children, locals = {}}) => {
38
+ const {correlationId} = useCorrelationId()
39
+ const headers = {
40
+ 'correlation-id': correlationId
41
+ }
42
+
43
+ const commerceApiConfig = locals.appConfig.commerceAPI
44
+
45
+ const appOrigin = getAppOrigin()
46
+
47
+ return (
48
+ <CommerceApiProvider
49
+ shortCode={commerceApiConfig.parameters.shortCode}
50
+ clientId={commerceApiConfig.parameters.clientId}
51
+ organizationId={commerceApiConfig.parameters.organizationId}
52
+ siteId={locals.site?.id}
53
+ locale={locals.locale?.id}
54
+ currency={locals.locale?.preferredCurrency}
55
+ redirectURI={`${appOrigin}/callback`}
56
+ proxy={`${appOrigin}${commerceApiConfig.proxyPath}`}
57
+ headers={headers}
58
+ OCAPISessionsURL={`${appOrigin}/mobify/proxy/ocapi/s/${locals.site?.id}/dw/shop/v22_8/sessions`}
59
+ {{#if answers.project.commerce.isSlasPrivate}}
60
+ // Set 'enablePWAKitPrivateClient' to true use SLAS private client login flows.
61
+ // Make sure to also enable useSLASPrivateClient in ssr.js when enabling this setting.
62
+ enablePWAKitPrivateClient={true}
63
+ {{/if}}
64
+ >
65
+ <MultiSiteProvider site={locals.site} locale={locals.locale} buildUrl={locals.buildUrl}>
66
+ <ChakraProvider theme={theme}>{children}</ChakraProvider>
67
+ </MultiSiteProvider>
68
+ <ReactQueryDevtools />
69
+ </CommerceApiProvider>
70
+ )
71
+ }
72
+
73
+ AppConfig.restore = (locals = {}) => {
74
+ const path =
75
+ typeof window === 'undefined'
76
+ ? locals.originalUrl
77
+ : `${window.location.pathname}${window.location.search}`
78
+ const site = resolveSiteFromUrl(path)
79
+ const locale = resolveLocaleFromUrl(path)
80
+
81
+ const {app: appConfig} = getConfig()
82
+ const apiConfig = {
83
+ ...appConfig.commerceAPI,
84
+ einsteinConfig: appConfig.einsteinAPI
85
+ }
86
+
87
+ apiConfig.parameters.siteId = site.id
88
+
89
+ locals.buildUrl = createUrlTemplate(appConfig, site.alias || site.id, locale.id)
90
+ locals.site = site
91
+ locals.locale = locale
92
+ locals.appConfig = appConfig
93
+ }
94
+
95
+ AppConfig.freeze = () => undefined
96
+
97
+ AppConfig.extraGetPropsArgs = (locals = {}) => {
98
+ return {
99
+ buildUrl: locals.buildUrl,
100
+ site: locals.site,
101
+ locale: locals.locale
102
+ }
103
+ }
104
+
105
+ AppConfig.propTypes = {
106
+ children: PropTypes.node,
107
+ locals: PropTypes.object
108
+ }
109
+
110
+ const isServerSide = typeof window === 'undefined'
111
+
112
+ // Recommended settings for PWA-Kit usages.
113
+ // NOTE: they will be applied on both server and client side.
114
+ // retry is always disabled on server side regardless of the value from the options
115
+ const options = {
116
+ queryClientConfig: {
117
+ defaultOptions: {
118
+ queries: {
119
+ retry: false,
120
+ refetchOnWindowFocus: false,
121
+ staleTime: 10 * 1000,
122
+ ...(isServerSide ? {retryOnMount: false} : {})
123
+ },
124
+ mutations: {
125
+ retry: false
126
+ }
127
+ }
128
+ }
129
+ }
130
+
131
+ export default withReactQuery(AppConfig, options)
@@ -0,0 +1,85 @@
1
+ /*
2
+ * Copyright (c) 2023, Salesforce, Inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+
8
+ 'use strict'
9
+
10
+ import path from 'path'
11
+ import {getRuntime} from '@salesforce/pwa-kit-runtime/ssr/server/express'
12
+ import {defaultPwaKitSecurityHeaders} from '@salesforce/pwa-kit-runtime/utils/middleware'
13
+ import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config'
14
+ import helmet from 'helmet'
15
+
16
+ const options = {
17
+ // The build directory (an absolute path)
18
+ buildDir: path.resolve(process.cwd(), 'build'),
19
+
20
+ // The cache time for SSR'd pages (defaults to 600 seconds)
21
+ defaultCacheTimeSeconds: 600,
22
+
23
+ // The contents of the config file for the current environment
24
+ mobify: getConfig(),
25
+
26
+ // The port that the local dev server listens on
27
+ port: 3000,
28
+
29
+ // The protocol on which the development Express app listens.
30
+ // Note that http://localhost is treated as a secure context for development,
31
+ // except by Safari.
32
+ protocol: 'http',
33
+
34
+ // Option for whether to set up a special endpoint for handling
35
+ // private SLAS clients
36
+ // Set this to false if using a SLAS public client
37
+ // When setting this to true, make sure to also set the PWA_KIT_SLAS_CLIENT_SECRET
38
+ // environment variable as this endpoint will return HTTP 501 if it is not set
39
+ useSLASPrivateClient: {{answers.project.commerce.isSlasPrivate}}
40
+ }
41
+
42
+ const runtime = getRuntime()
43
+
44
+ const {handler} = runtime.createHandler(options, (app) => {
45
+ // Set default HTTP security headers required by PWA Kit
46
+ app.use(defaultPwaKitSecurityHeaders)
47
+ // Set custom HTTP security headers
48
+ app.use(
49
+ helmet({
50
+ contentSecurityPolicy: {
51
+ useDefaults: true,
52
+ directives: {
53
+ 'img-src': [
54
+ // Default source for product images - replace with your CDN
55
+ '*.commercecloud.salesforce.com'
56
+ ],
57
+ 'script-src': [
58
+ // Used by the service worker in /worker/main.js
59
+ 'storage.googleapis.com'
60
+ ],
61
+ 'connect-src': [
62
+ // Connect to Einstein APIs
63
+ 'api.cquotient.com'
64
+ ]
65
+ }
66
+ }
67
+ })
68
+ )
69
+
70
+ // Handle the redirect from SLAS as to avoid error
71
+ app.get('/callback?*', (req, res) => {
72
+ // This endpoint does nothing and is not expected to change
73
+ // Thus we cache it for a year to maximize performance
74
+ res.set('Cache-Control', `max-age=31536000`)
75
+ res.send()
76
+ })
77
+ app.get('/robots.txt', runtime.serveStaticFile('static/robots.txt'))
78
+ app.get('/favicon.ico', runtime.serveStaticFile('static/ico/favicon.ico'))
79
+
80
+ app.get('/worker.js(.map)?', runtime.serveServiceWorker)
81
+ app.get('*', runtime.render)
82
+ })
83
+ // SSR requires that we export a single handler function called 'get', that
84
+ // supports AWS use of the server that we created above.
85
+ export const get = handler
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/pwa-kit-create-app",
3
- "version": "3.5.0-alpha.0",
3
+ "version": "3.5.0-alpha.1",
4
4
  "description": "Salesforce's project generator tool",
5
5
  "homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/pwa-kit-create-app#readme",
6
6
  "bugs": {
@@ -38,13 +38,13 @@
38
38
  "tar": "^6.2.1"
39
39
  },
40
40
  "devDependencies": {
41
- "@salesforce/pwa-kit-dev": "3.5.0-alpha.0",
42
- "internal-lib-build": "3.5.0-alpha.0",
41
+ "@salesforce/pwa-kit-dev": "3.5.0-alpha.1",
42
+ "internal-lib-build": "3.5.0-alpha.1",
43
43
  "verdaccio": "^5.22.1"
44
44
  },
45
45
  "engines": {
46
46
  "node": "^16.11.0 || ^18.0.0 || ^20.0.0",
47
47
  "npm": "^8.0.0 || ^9.0.0 || ^10.0.0"
48
48
  },
49
- "gitHead": "0edd6b2ea26b9c23502755b6ccc7316a538a4c7a"
49
+ "gitHead": "2df9f520e6de6585926743fb72bf8e77d515dcf1"
50
50
  }
@@ -187,6 +187,21 @@ const RETAIL_REACT_APP_QUESTIONS = [
187
187
  message: 'What is your SLAS Client ID?',
188
188
  validate: validClientId
189
189
  },
190
+ {
191
+ name: 'project.commerce.isSlasPrivate',
192
+ message: 'Is your SLAS client private?',
193
+ type: 'list',
194
+ choices: [
195
+ {
196
+ name: 'Yes',
197
+ value: true
198
+ },
199
+ {
200
+ name: 'No',
201
+ value: false
202
+ }
203
+ ]
204
+ },
190
205
  {
191
206
  name: 'project.commerce.siteId',
192
207
  message: 'What is your Site ID in Business Manager?',
@@ -248,6 +263,7 @@ const PRESETS = [
248
263
  ['project.commerce.siteId']: 'RefArch',
249
264
  ['project.commerce.organizationId']: 'f_ecom_zzte_053',
250
265
  ['project.commerce.shortCode']: 'kv7kzm78',
266
+ ['project.commerce.isSlasPrivate']: false,
251
267
  ['project.einstein.clientId']: '1ea06c6e-c936-4324-bcf0-fada93f83bb1',
252
268
  ['project.einstein.siteId']: 'aaij-MobileFirst'
253
269
  },
@@ -272,6 +288,32 @@ const PRESETS = [
272
288
  ['project.commerce.siteId']: 'RefArch',
273
289
  ['project.commerce.organizationId']: 'f_ecom_zzrf_001',
274
290
  ['project.commerce.shortCode']: 'kv7kzm78',
291
+ ['project.commerce.isSlasPrivate']: false,
292
+ ['project.einstein.clientId']: '1ea06c6e-c936-4324-bcf0-fada93f83bb1',
293
+ ['project.einstein.siteId']: 'aaij-MobileFirst'
294
+ },
295
+ assets: ['translations'],
296
+ private: true
297
+ },
298
+ {
299
+ id: 'retail-react-app-private-slas-client',
300
+ name: 'Retail React App Private SLAS client project',
301
+ description: '',
302
+ templateSource: {
303
+ type: TEMPLATE_SOURCE_NPM,
304
+ id: '@salesforce/retail-react-app'
305
+ },
306
+ questions: [...EXTENSIBILITY_QUESTIONS, ...RETAIL_REACT_APP_QUESTIONS],
307
+ answers: {
308
+ ['project.extend']: true,
309
+ ['project.hybrid']: false,
310
+ ['project.name']: 'retail-react-app',
311
+ ['project.commerce.instanceUrl']: 'https://zzrf-002.dx.commercecloud.salesforce.com',
312
+ ['project.commerce.clientId']: '89655706-9a0d-49ba-a1e5-18bb2d616374',
313
+ ['project.commerce.siteId']: 'RefArch',
314
+ ['project.commerce.organizationId']: 'f_ecom_zzrf_002',
315
+ ['project.commerce.shortCode']: 'kv7kzm78',
316
+ ['project.commerce.isSlasPrivate']: true,
275
317
  ['project.einstein.clientId']: '1ea06c6e-c936-4324-bcf0-fada93f83bb1',
276
318
  ['project.einstein.siteId']: 'aaij-MobileFirst'
277
319
  },
@@ -280,7 +322,7 @@ const PRESETS = [
280
322
  },
281
323
  {
282
324
  id: 'retail-react-app-hybrid-test-project',
283
- name: 'Retail React App Hybrid Test Project',
325
+ name: 'Retail React App Hybrid Test Private SLAS Project',
284
326
  description: '',
285
327
  templateSource: {
286
328
  type: TEMPLATE_SOURCE_NPM,
@@ -292,12 +334,38 @@ const PRESETS = [
292
334
  ['project.hybrid']: true,
293
335
  ['project.name']: 'retail-react-app',
294
336
  ['project.commerce.instanceUrl']: 'https://test.phased-launch-testing.com/',
295
- ['project.commerce.clientId']: '50b359ea-4224-4125-b75d-dd80ff4b0f00',
337
+ ['project.commerce.clientId']: '99b4e081-00cf-454a-95b0-26ac2b824931',
296
338
  ['project.commerce.siteId']: 'RefArch',
297
339
  ['project.commerce.organizationId']: 'f_ecom_bdpx_dev',
298
340
  ['project.commerce.shortCode']: 'xitgmcd3',
299
341
  ['project.einstein.clientId']: '1ea06c6e-c936-4324-bcf0-fada93f83bb1',
300
- ['project.einstein.siteId']: 'aaij-MobileFirst'
342
+ ['project.einstein.siteId']: 'aaij-MobileFirst',
343
+ ['project.commerce.isSlasPrivate']: true
344
+ },
345
+ assets: ['translations'],
346
+ private: true
347
+ },
348
+ {
349
+ id: 'retail-react-app-hybrid-public-client-test-project',
350
+ name: 'Retail React App Hybrid Test Public SLAS client project',
351
+ description: '',
352
+ templateSource: {
353
+ type: TEMPLATE_SOURCE_NPM,
354
+ id: '@salesforce/retail-react-app'
355
+ },
356
+ questions: [...EXTENSIBILITY_QUESTIONS, ...HYBRID_QUESTIONS, ...RETAIL_REACT_APP_QUESTIONS],
357
+ answers: {
358
+ ['project.extend']: true,
359
+ ['project.hybrid']: true,
360
+ ['project.name']: 'retail-react-app',
361
+ ['project.commerce.instanceUrl']: 'https://www.phased-launch-testing.com/',
362
+ ['project.commerce.clientId']: 'e7e22b7f-a904-4f3a-8022-49dbee696485',
363
+ ['project.commerce.siteId']: 'RefArch',
364
+ ['project.commerce.organizationId']: 'f_ecom_bjnl_prd',
365
+ ['project.commerce.shortCode']: 'performance-001',
366
+ ['project.einstein.clientId']: '1ea06c6e-c936-4324-bcf0-fada93f83bb1',
367
+ ['project.einstein.siteId']: 'aaij-MobileFirst',
368
+ ['project.commerce.isSlasPrivate']: false
301
369
  },
302
370
  assets: ['translations'],
303
371
  private: true
Binary file
Binary file
Binary file
Binary file