@salesforce/pwa-kit-create-app 3.12.0-preview.0 → 3.12.0-preview.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.
- package/assets/bootstrap/js/config/default.js.hbs +14 -0
- package/assets/bootstrap/js/overrides/app/components/_app-config/index.jsx.hbs +12 -4
- package/assets/bootstrap/js/overrides/app/constants.js.hbs +3 -3
- package/assets/bootstrap/js/overrides/app/main.jsx +2 -1
- package/assets/bootstrap/js/overrides/app/ssr.js.hbs +40 -23
- package/assets/templates/@salesforce/retail-react-app/app/components/_app-config/index.jsx.hbs +12 -4
- package/assets/templates/@salesforce/retail-react-app/app/ssr.js.hbs +40 -22
- package/assets/templates/@salesforce/retail-react-app/config/default.js.hbs +10 -0
- package/package.json +4 -4
- package/program.json +49 -9
- package/scripts/create-mobify-app.js +6 -23
- package/templates/express-minimal.tar.gz +0 -0
- package/templates/mrt-reference-app.tar.gz +0 -0
- package/templates/retail-react-app.tar.gz +0 -0
- package/templates/typescript-minimal.tar.gz +0 -0
|
@@ -10,6 +10,16 @@ const {parseCommerceAgentSettings} = require('./utils.js')
|
|
|
10
10
|
|
|
11
11
|
module.exports = {
|
|
12
12
|
app: {
|
|
13
|
+
// Enable the store locator and shop the store feature.
|
|
14
|
+
storeLocatorEnabled: true,
|
|
15
|
+
// Enable the multi-ship feature.
|
|
16
|
+
multishipEnabled: true,
|
|
17
|
+
// Enable partial hydration capabilities via Island component
|
|
18
|
+
{{#if answers.project.partialHydrationEnabled}}
|
|
19
|
+
partialHydrationEnabled: {{answers.project.partialHydrationEnabled}},
|
|
20
|
+
{{else}}
|
|
21
|
+
partialHydrationEnabled: false,
|
|
22
|
+
{{/if}}
|
|
13
23
|
// Commerce shopping agent configuration for embedded messaging service
|
|
14
24
|
// This enables an agentic shopping experience in the application
|
|
15
25
|
// This property accepts either a JSON string or a plain JavaScript object.
|
|
@@ -117,6 +127,10 @@ module.exports = {
|
|
|
117
127
|
tenantId: '{{answers.project.dataCloud.tenantId}}'
|
|
118
128
|
}
|
|
119
129
|
},
|
|
130
|
+
// Experimental: The base path for the app. This is the path that will be prepended to all /mobify routes,
|
|
131
|
+
// callback routes, and Express routes.
|
|
132
|
+
// Setting this to `/` or an empty string will result in the above routes not having a base path.
|
|
133
|
+
envBasePath: '/',
|
|
120
134
|
// This list contains server-side only libraries that you don't want to be compiled by webpack
|
|
121
135
|
externals: [],
|
|
122
136
|
// Page not found url for your app
|
|
@@ -31,6 +31,7 @@ import {withReactQuery} from '@salesforce/pwa-kit-react-sdk/ssr/universal/compon
|
|
|
31
31
|
import {useCorrelationId} from '@salesforce/pwa-kit-react-sdk/ssr/universal/hooks'
|
|
32
32
|
import {getAppOrigin} from '@salesforce/pwa-kit-react-sdk/utils/url'
|
|
33
33
|
import {ReactQueryDevtools} from '@tanstack/react-query-devtools'
|
|
34
|
+
import {generateSfdcUserAgent} from '@salesforce/retail-react-app/app/utils/sfdc-user-agent-utils'
|
|
34
35
|
import {
|
|
35
36
|
DEFAULT_DNT_STATE,
|
|
36
37
|
STORE_LOCATOR_RADIUS,
|
|
@@ -42,6 +43,8 @@ import {
|
|
|
42
43
|
STORE_LOCATOR_SUPPORTED_COUNTRIES
|
|
43
44
|
} from '@salesforce/retail-react-app/app/constants'
|
|
44
45
|
|
|
46
|
+
const sfdcUserAgent = generateSfdcUserAgent()
|
|
47
|
+
|
|
45
48
|
/**
|
|
46
49
|
* Use the AppConfig component to inject extra arguments into the getProps
|
|
47
50
|
* methods for all Route Components in the app – typically you'd want to do this
|
|
@@ -53,7 +56,8 @@ import {
|
|
|
53
56
|
const AppConfig = ({children, locals = {}}) => {
|
|
54
57
|
const {correlationId} = useCorrelationId()
|
|
55
58
|
const headers = {
|
|
56
|
-
'correlation-id': correlationId
|
|
59
|
+
'correlation-id': correlationId,
|
|
60
|
+
sfdc_user_agent: sfdcUserAgent
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
const commerceApiConfig = locals.appConfig.commerceAPI
|
|
@@ -94,12 +98,16 @@ const AppConfig = ({children, locals = {}}) => {
|
|
|
94
98
|
defaultDnt={DEFAULT_DNT_STATE}
|
|
95
99
|
logger={createLogger({packageName: 'commerce-sdk-react'})}
|
|
96
100
|
passwordlessLoginCallbackURI={passwordlessLoginCallbackURI}
|
|
97
|
-
|
|
98
|
-
// Set 'enablePWAKitPrivateClient' to true use SLAS private client login flows.
|
|
101
|
+
// Set 'enablePWAKitPrivateClient' to true to use SLAS private client login flows.
|
|
99
102
|
// Make sure to also enable useSLASPrivateClient in ssr.js when enabling this setting.
|
|
103
|
+
{{#if answers.project.commerce.isSlasPrivate}}
|
|
100
104
|
enablePWAKitPrivateClient={true}
|
|
105
|
+
{{else}}
|
|
106
|
+
enablePWAKitPrivateClient={false}
|
|
101
107
|
{{/if}}
|
|
102
|
-
|
|
108
|
+
privateClientProxyEndpoint={slasPrivateClientProxyEndpoint}
|
|
109
|
+
// Uncomment 'hybridAuthEnabled' if the current site has Hybrid Auth enabled. Do NOT set this flag for hybrid storefronts using Plugin SLAS.
|
|
110
|
+
// hybridAuthEnabled={true}
|
|
103
111
|
>
|
|
104
112
|
<MultiSiteProvider site={locals.site} locale={locals.locale} buildUrl={locals.buildUrl}>
|
|
105
113
|
<StoreLocatorProvider config={storeLocatorConfig}>
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
/*
|
|
8
|
+
/*
|
|
9
9
|
Hello there! This is a demonstration of how to override a file from the base template.
|
|
10
|
-
|
|
11
|
-
It's necessary that the module export interface remain consistent,
|
|
10
|
+
|
|
11
|
+
It's necessary that the module export interface remain consistent,
|
|
12
12
|
as other files in the base template rely on constants.js, thus we
|
|
13
13
|
import the underlying constants.js, modifies it and re-export it.
|
|
14
14
|
*/
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
6
|
*/
|
|
7
7
|
import {start, registerServiceWorker} from '@salesforce/pwa-kit-react-sdk/ssr/browser/main'
|
|
8
|
+
import {getEnvBasePath} from '@salesforce/pwa-kit-runtime/utils/ssr-namespace-paths'
|
|
8
9
|
|
|
9
10
|
const main = () => {
|
|
10
11
|
// The path to your service worker should match what is set up in ssr.js
|
|
11
|
-
return Promise.all([start(), registerServiceWorker(
|
|
12
|
+
return Promise.all([start(), registerServiceWorker(`${getEnvBasePath()}/worker.js`)])
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
main()
|
|
@@ -44,6 +44,13 @@ const options = {
|
|
|
44
44
|
// environment variable as this endpoint will return HTTP 501 if it is not set
|
|
45
45
|
useSLASPrivateClient: {{answers.project.commerce.isSlasPrivate}},
|
|
46
46
|
|
|
47
|
+
// If you wish to use additional SLAS endpoints that require private clients,
|
|
48
|
+
// customize this regex to include the additional endpoints the custom SLAS
|
|
49
|
+
// private client secret handler will inject an Authorization header.
|
|
50
|
+
// The default regex is defined in this file: https://github.com/SalesforceCommerceCloud/pwa-kit/blob/develop/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js
|
|
51
|
+
// applySLASPrivateClientToEndpoints:
|
|
52
|
+
// /\/oauth2\/(token|passwordless\/(login|token)|password\/(reset|action))/,
|
|
53
|
+
|
|
47
54
|
// If this is enabled, any HTTP header that has a non ASCII value will be URI encoded
|
|
48
55
|
// If there any HTTP headers that have been encoded, an additional header will be
|
|
49
56
|
// passed, `x-encoded-headers`, containing a comma separated list
|
|
@@ -282,35 +289,45 @@ const {handler} = runtime.createHandler(options, (app) => {
|
|
|
282
289
|
// Set default HTTP security headers required by PWA Kit
|
|
283
290
|
app.use(defaultPwaKitSecurityHeaders)
|
|
284
291
|
// Set custom HTTP security headers
|
|
292
|
+
{{#if answers.project.contentSecurityPolicy}}
|
|
293
|
+
const contentSecurityPolicy = {{{json answers.project.contentSecurityPolicy}}}
|
|
294
|
+
{{else}}
|
|
295
|
+
const contentSecurityPolicy = {
|
|
296
|
+
useDefaults: true,
|
|
297
|
+
directives: {
|
|
298
|
+
'img-src': [
|
|
299
|
+
// Default source for product images - replace with your CDN
|
|
300
|
+
'*.commercecloud.salesforce.com',
|
|
301
|
+
'*.demandware.net'
|
|
302
|
+
],
|
|
303
|
+
'script-src': [
|
|
304
|
+
// Used by the service worker in /worker/main.js
|
|
305
|
+
'storage.googleapis.com'
|
|
306
|
+
],
|
|
307
|
+
'connect-src': [
|
|
308
|
+
// Connect to Einstein APIs
|
|
309
|
+
'api.cquotient.com',
|
|
310
|
+
// Connect to DataCloud APIs
|
|
311
|
+
'*.c360a.salesforce.com',
|
|
312
|
+
// Connect to SCRT2 URLs
|
|
313
|
+
'*.salesforce-scrt.com'
|
|
314
|
+
],
|
|
315
|
+
'frame-src': [
|
|
316
|
+
// Allow frames from Salesforce site.com (Needed for MIAW)
|
|
317
|
+
'*.site.com'
|
|
318
|
+
]
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
{{/if}}
|
|
322
|
+
|
|
285
323
|
app.use(
|
|
286
324
|
helmet({
|
|
287
|
-
contentSecurityPolicy
|
|
288
|
-
useDefaults: true,
|
|
289
|
-
directives: {
|
|
290
|
-
'img-src': [
|
|
291
|
-
// Default source for product images - replace with your CDN
|
|
292
|
-
'*.commercecloud.salesforce.com',
|
|
293
|
-
'*.demandware.net'
|
|
294
|
-
],
|
|
295
|
-
'script-src': [
|
|
296
|
-
// Used by the service worker in /worker/main.js
|
|
297
|
-
'storage.googleapis.com'
|
|
298
|
-
],
|
|
299
|
-
'connect-src': [
|
|
300
|
-
// Connect to Einstein APIs
|
|
301
|
-
'api.cquotient.com',
|
|
302
|
-
'*.c360a.salesforce.com'
|
|
303
|
-
]
|
|
304
|
-
},
|
|
305
|
-
referrerPolicy: {
|
|
306
|
-
policy: 'strict-origin-when-cross-origin'
|
|
307
|
-
}
|
|
308
|
-
}
|
|
325
|
+
contentSecurityPolicy
|
|
309
326
|
})
|
|
310
327
|
)
|
|
311
328
|
|
|
312
329
|
// Handle the redirect from SLAS as to avoid error
|
|
313
|
-
app.get('/callback
|
|
330
|
+
app.get('/callback', (req, res) => {
|
|
314
331
|
// This endpoint does nothing and is not expected to change
|
|
315
332
|
// Thus we cache it for a year to maximize performance
|
|
316
333
|
res.set('Cache-Control', `max-age=31536000`)
|
package/assets/templates/@salesforce/retail-react-app/app/components/_app-config/index.jsx.hbs
CHANGED
|
@@ -31,6 +31,7 @@ import {CommerceApiProvider} from '@salesforce/commerce-sdk-react'
|
|
|
31
31
|
import {withReactQuery} from '@salesforce/pwa-kit-react-sdk/ssr/universal/components/with-react-query'
|
|
32
32
|
import {useCorrelationId} from '@salesforce/pwa-kit-react-sdk/ssr/universal/hooks'
|
|
33
33
|
import {ReactQueryDevtools} from '@tanstack/react-query-devtools'
|
|
34
|
+
import {generateSfdcUserAgent} from '@salesforce/retail-react-app/app/utils/sfdc-user-agent-utils'
|
|
34
35
|
import {DEFAULT_DNT_STATE} from '@salesforce/retail-react-app/app/constants'
|
|
35
36
|
import {
|
|
36
37
|
STORE_LOCATOR_RADIUS,
|
|
@@ -42,6 +43,8 @@ import {
|
|
|
42
43
|
STORE_LOCATOR_SUPPORTED_COUNTRIES
|
|
43
44
|
} from '@salesforce/retail-react-app/app/constants'
|
|
44
45
|
|
|
46
|
+
const sfdcUserAgent = generateSfdcUserAgent()
|
|
47
|
+
|
|
45
48
|
/**
|
|
46
49
|
* Use the AppConfig component to inject extra arguments into the getProps
|
|
47
50
|
* methods for all Route Components in the app – typically you'd want to do this
|
|
@@ -53,7 +56,8 @@ import {
|
|
|
53
56
|
const AppConfig = ({children, locals = {}}) => {
|
|
54
57
|
const {correlationId} = useCorrelationId()
|
|
55
58
|
const headers = {
|
|
56
|
-
'correlation-id': correlationId
|
|
59
|
+
'correlation-id': correlationId,
|
|
60
|
+
sfdc_user_agent: sfdcUserAgent
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
const commerceApiConfig = locals.appConfig.commerceAPI
|
|
@@ -94,12 +98,16 @@ const AppConfig = ({children, locals = {}}) => {
|
|
|
94
98
|
defaultDnt={DEFAULT_DNT_STATE}
|
|
95
99
|
logger={createLogger({packageName: 'commerce-sdk-react'})}
|
|
96
100
|
passwordlessLoginCallbackURI={passwordlessCallback}
|
|
97
|
-
|
|
98
|
-
// Set 'enablePWAKitPrivateClient' to true use SLAS private client login flows.
|
|
101
|
+
// Set 'enablePWAKitPrivateClient' to true to use SLAS private client login flows.
|
|
99
102
|
// Make sure to also enable useSLASPrivateClient in ssr.js when enabling this setting.
|
|
103
|
+
{{#if answers.project.commerce.isSlasPrivate}}
|
|
100
104
|
enablePWAKitPrivateClient={true}
|
|
105
|
+
{{else}}
|
|
106
|
+
enablePWAKitPrivateClient={false}
|
|
101
107
|
{{/if}}
|
|
102
|
-
|
|
108
|
+
privateClientProxyEndpoint={slasPrivateClientProxyEndpoint}
|
|
109
|
+
// Uncomment 'hybridAuthEnabled' if the current site has Hybrid Auth enabled. Do NOT set this flag for hybrid storefronts using Plugin SLAS.
|
|
110
|
+
// hybridAuthEnabled={true}
|
|
103
111
|
>
|
|
104
112
|
<MultiSiteProvider site={locals.site} locale={locals.locale} buildUrl={locals.buildUrl}>
|
|
105
113
|
<StoreLocatorProvider config={storeLocatorConfig}>
|
|
@@ -44,6 +44,13 @@ const options = {
|
|
|
44
44
|
// environment variable as this endpoint will return HTTP 501 if it is not set
|
|
45
45
|
useSLASPrivateClient: {{answers.project.commerce.isSlasPrivate}},
|
|
46
46
|
|
|
47
|
+
// If you wish to use additional SLAS endpoints that require private clients,
|
|
48
|
+
// customize this regex to include the additional endpoints the custom SLAS
|
|
49
|
+
// private client secret handler will inject an Authorization header.
|
|
50
|
+
// The default regex is defined in this file: https://github.com/SalesforceCommerceCloud/pwa-kit/blob/develop/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js
|
|
51
|
+
// applySLASPrivateClientToEndpoints:
|
|
52
|
+
// /\/oauth2\/(token|passwordless\/(login|token)|password\/(reset|action))/,
|
|
53
|
+
|
|
47
54
|
// If this is enabled, any HTTP header that has a non ASCII value will be URI encoded
|
|
48
55
|
// If there any HTTP headers that have been encoded, an additional header will be
|
|
49
56
|
// passed, `x-encoded-headers`, containing a comma separated list
|
|
@@ -282,34 +289,45 @@ const {handler} = runtime.createHandler(options, (app) => {
|
|
|
282
289
|
// Set default HTTP security headers required by PWA Kit
|
|
283
290
|
app.use(defaultPwaKitSecurityHeaders)
|
|
284
291
|
// Set custom HTTP security headers
|
|
292
|
+
{{#if answers.project.contentSecurityPolicy}}
|
|
293
|
+
const contentSecurityPolicy = {{{json answers.project.contentSecurityPolicy}}}
|
|
294
|
+
{{else}}
|
|
295
|
+
const contentSecurityPolicy = {
|
|
296
|
+
useDefaults: true,
|
|
297
|
+
directives: {
|
|
298
|
+
'img-src': [
|
|
299
|
+
// Default source for product images - replace with your CDN
|
|
300
|
+
'*.commercecloud.salesforce.com',
|
|
301
|
+
'*.demandware.net'
|
|
302
|
+
],
|
|
303
|
+
'script-src': [
|
|
304
|
+
// Used by the service worker in /worker/main.js
|
|
305
|
+
'storage.googleapis.com'
|
|
306
|
+
],
|
|
307
|
+
'connect-src': [
|
|
308
|
+
// Connect to Einstein APIs
|
|
309
|
+
'api.cquotient.com',
|
|
310
|
+
// Connect to DataCloud APIs
|
|
311
|
+
'*.c360a.salesforce.com',
|
|
312
|
+
// Connect to SCRT2 URLs
|
|
313
|
+
'*.salesforce-scrt.com'
|
|
314
|
+
],
|
|
315
|
+
'frame-src': [
|
|
316
|
+
// Allow frames from Salesforce site.com (Needed for MIAW)
|
|
317
|
+
'*.site.com'
|
|
318
|
+
]
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
{{/if}}
|
|
322
|
+
|
|
285
323
|
app.use(
|
|
286
324
|
helmet({
|
|
287
|
-
contentSecurityPolicy
|
|
288
|
-
useDefaults: true,
|
|
289
|
-
directives: {
|
|
290
|
-
'img-src': [
|
|
291
|
-
// Default source for product images - replace with your CDN
|
|
292
|
-
'*.commercecloud.salesforce.com'
|
|
293
|
-
],
|
|
294
|
-
'script-src': [
|
|
295
|
-
// Used by the service worker in /worker/main.js
|
|
296
|
-
'storage.googleapis.com'
|
|
297
|
-
],
|
|
298
|
-
'connect-src': [
|
|
299
|
-
// Connect to Einstein APIs
|
|
300
|
-
'api.cquotient.com',
|
|
301
|
-
'*.c360a.salesforce.com'
|
|
302
|
-
]
|
|
303
|
-
},
|
|
304
|
-
referrerPolicy: {
|
|
305
|
-
policy: 'strict-origin-when-cross-origin'
|
|
306
|
-
}
|
|
307
|
-
}
|
|
325
|
+
contentSecurityPolicy
|
|
308
326
|
})
|
|
309
327
|
)
|
|
310
328
|
|
|
311
329
|
// Handle the redirect from SLAS as to avoid error
|
|
312
|
-
app.get('/callback
|
|
330
|
+
app.get('/callback', (req, res) => {
|
|
313
331
|
// This endpoint does nothing and is not expected to change
|
|
314
332
|
// Thus we cache it for a year to maximize performance
|
|
315
333
|
res.set('Cache-Control', `max-age=31536000`)
|
|
@@ -10,6 +10,16 @@ const {parseCommerceAgentSettings} = require('./utils.js')
|
|
|
10
10
|
|
|
11
11
|
module.exports = {
|
|
12
12
|
app: {
|
|
13
|
+
// Enable the store locator and shop the store feature.
|
|
14
|
+
storeLocatorEnabled: true,
|
|
15
|
+
// Enable the multi-ship feature.
|
|
16
|
+
multishipEnabled: true,
|
|
17
|
+
// Enable partial hydration capabilities via Island component
|
|
18
|
+
{{#if answers.project.partialHydrationEnabled}}
|
|
19
|
+
partialHydrationEnabled: {{answers.project.partialHydrationEnabled}},
|
|
20
|
+
{{else}}
|
|
21
|
+
partialHydrationEnabled: false,
|
|
22
|
+
{{/if}}
|
|
13
23
|
// Commerce shopping agent configuration for embedded messaging service
|
|
14
24
|
// This enables an agentic shopping experience in the application
|
|
15
25
|
// This property accepts either a JSON string or a plain JavaScript object.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/pwa-kit-create-app",
|
|
3
|
-
"version": "3.12.0-preview.
|
|
3
|
+
"version": "3.12.0-preview.2",
|
|
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": {
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
"tar": "^6.2.1"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@salesforce/pwa-kit-dev": "3.12.0-preview.
|
|
43
|
-
"internal-lib-build": "3.12.0-preview.
|
|
42
|
+
"@salesforce/pwa-kit-dev": "3.12.0-preview.2",
|
|
43
|
+
"internal-lib-build": "3.12.0-preview.2",
|
|
44
44
|
"verdaccio": "^5.22.1"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
|
47
47
|
"node": "^16.11.0 || ^18.0.0 || ^20.0.0 || ^22.0.0",
|
|
48
48
|
"npm": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "c0d7ff4673e54ecb119ca4aff5b919f0064b6539"
|
|
51
51
|
}
|
package/program.json
CHANGED
|
@@ -472,6 +472,54 @@
|
|
|
472
472
|
},
|
|
473
473
|
"private": true
|
|
474
474
|
},
|
|
475
|
+
{
|
|
476
|
+
"id": "retail-react-app-performance-tests",
|
|
477
|
+
"name": "Retail React App for performance tests",
|
|
478
|
+
"description": "",
|
|
479
|
+
"templateId": "retail-react-app",
|
|
480
|
+
"answers": {
|
|
481
|
+
"project.extend": false,
|
|
482
|
+
"project.hybrid": false,
|
|
483
|
+
"project.name": "retail-react-app",
|
|
484
|
+
"project.commerce.instanceUrl": "https://zzrf-001.dx.commercecloud.salesforce.com",
|
|
485
|
+
"project.commerce.clientId": "9629ef22-f8b8-4987-90ac-b815be3940c8",
|
|
486
|
+
"project.commerce.siteId": "SiteNemesis",
|
|
487
|
+
"project.commerce.organizationId": "f_ecom_tbbn_prd",
|
|
488
|
+
"project.commerce.shortCode": "performance-001",
|
|
489
|
+
"project.commerce.isSlasPrivate": true,
|
|
490
|
+
"project.einstein.clientId": "1ea06c6e-c936-4324-bcf0-fada93f83bb1",
|
|
491
|
+
"project.einstein.siteId": "aaij-MobileFirst",
|
|
492
|
+
"project.dataCloud.appSourceId": "7ae070a6-f4ec-4def-a383-d9cacc3f20a1",
|
|
493
|
+
"project.dataCloud.tenantId": "g82wgnrvm-ywk9dggrrw8mtggy.pc-rnd",
|
|
494
|
+
"project.demo.enableDemoSettings": false,
|
|
495
|
+
|
|
496
|
+
"project.partialHydrationEnabled": true,
|
|
497
|
+
"project.contentSecurityPolicy": {
|
|
498
|
+
"useDefaults": true,
|
|
499
|
+
"directives": {
|
|
500
|
+
"img-src": [
|
|
501
|
+
"*.commercecloud.salesforce.com",
|
|
502
|
+
"*.demandware.net",
|
|
503
|
+
"*.sfcc-store-internal.net"
|
|
504
|
+
],
|
|
505
|
+
"script-src": [
|
|
506
|
+
"storage.googleapis.com",
|
|
507
|
+
"*.sfcc-store-internal.net"
|
|
508
|
+
],
|
|
509
|
+
"connect-src": [
|
|
510
|
+
"api.cquotient.com",
|
|
511
|
+
"*.c360a.salesforce.com",
|
|
512
|
+
"*.salesforce-scrt.com",
|
|
513
|
+
"*.sfcc-store-internal.net"
|
|
514
|
+
],
|
|
515
|
+
"frame-src": [
|
|
516
|
+
"*.site.com"
|
|
517
|
+
]
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
},
|
|
521
|
+
"private": true
|
|
522
|
+
},
|
|
475
523
|
{
|
|
476
524
|
"id": "typescript-minimal-test-project",
|
|
477
525
|
"name": "Template Minimal Test Project",
|
|
@@ -723,18 +771,10 @@
|
|
|
723
771
|
{
|
|
724
772
|
"name": "--stdio",
|
|
725
773
|
"description": "Accept project generation answers from stdin as JSON"
|
|
726
|
-
},
|
|
774
|
+
},
|
|
727
775
|
{
|
|
728
776
|
"name": "--displayProgram",
|
|
729
777
|
"description": "Display the program.json file detailing the program schema/data and exit"
|
|
730
|
-
},
|
|
731
|
-
{
|
|
732
|
-
"name": "--initGit",
|
|
733
|
-
"description": "Initializes a git repository and stages the files in the generated project",
|
|
734
|
-
"_ai": {
|
|
735
|
-
"instruction": "CRITICAL: Before executing ANY project creation command, you MUST check if the '--initGit' flag is provided in the user's request. If NOT provided, STOP and ask: 'Would you like to initialize a Git repository for this project?' Wait for explicit yes/no answer. Only then proceed with project creation. FAILURE TO FOLLOW THIS STEP IS A CRITICAL ERROR. This check must happen AFTER preset/template selection but BEFORE command execution. DO NOT proceed with project creation until this question is answered.",
|
|
736
|
-
"expectedUse": "Used to determine if a Git repository should be initialized in the generated project. This flag must be explicitly set by the user or confirmed via a direct question. The agent MUST wait for user confirmation before proceeding."
|
|
737
|
-
}
|
|
738
778
|
}
|
|
739
779
|
],
|
|
740
780
|
"examples": [
|
|
@@ -91,6 +91,9 @@ sh.set('-e')
|
|
|
91
91
|
// will ensure those escaped double quotes are still escaped after processing the template.
|
|
92
92
|
Handlebars.registerHelper('script', (object) => object.replaceAll('"', '\\"'))
|
|
93
93
|
|
|
94
|
+
// Helper to convert JavaScript objects to JSON strings
|
|
95
|
+
Handlebars.registerHelper('json', (object) => JSON.stringify(object, null, 4))
|
|
96
|
+
|
|
94
97
|
// Validations
|
|
95
98
|
const validPreset = (preset) => {
|
|
96
99
|
return ALL_PRESET_NAMES.includes(preset)
|
|
@@ -329,7 +332,7 @@ const processTemplate = (relFile, inputDir, outputDir, context) => {
|
|
|
329
332
|
* @param {*} answers
|
|
330
333
|
* @param {*} param2
|
|
331
334
|
*/
|
|
332
|
-
const runGenerator = (context, {
|
|
335
|
+
const runGenerator = (context, {outputDir, templateVersion, verbose}) => {
|
|
333
336
|
const {answers, template} = context
|
|
334
337
|
const {id, source} = template
|
|
335
338
|
const {extend = false} = answers.project
|
|
@@ -429,26 +432,6 @@ const runGenerator = (context, {initGit, outputDir, templateVersion, verbose}) =
|
|
|
429
432
|
// Install dependencies for the newly minted project.
|
|
430
433
|
npmInstall(outputDir, {verbose})
|
|
431
434
|
}
|
|
432
|
-
|
|
433
|
-
// Initialize a git repository if the --initGit flag is provided.
|
|
434
|
-
if (initGit) {
|
|
435
|
-
initGitRepo(outputDir)
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
* Initializes a git repository in the specified directory, adds all files, and checks for git installation.
|
|
441
|
-
* @param {string} outputDir - The directory in which to initialize the git repository.
|
|
442
|
-
*/
|
|
443
|
-
const initGitRepo = (outputDir) => {
|
|
444
|
-
if (!sh.which('git')) {
|
|
445
|
-
console.error(
|
|
446
|
-
'Error: git is not installed or not found in PATH. Please install git to initialize a repository.'
|
|
447
|
-
)
|
|
448
|
-
process.exit(1)
|
|
449
|
-
}
|
|
450
|
-
sh.exec(`git init`, {cwd: outputDir})
|
|
451
|
-
sh.exec(`git add .`, {cwd: outputDir})
|
|
452
435
|
}
|
|
453
436
|
|
|
454
437
|
const foundNode = process.versions.node
|
|
@@ -554,7 +537,7 @@ const main = async (opts) => {
|
|
|
554
537
|
let isPreset = false
|
|
555
538
|
let answers = {}
|
|
556
539
|
let selectedTemplate
|
|
557
|
-
let {outputDir, verbose, preset, templateVersion, stdio, displayProgram
|
|
540
|
+
let {outputDir, verbose, preset, templateVersion, stdio, displayProgram} = opts
|
|
558
541
|
const {prompt} = inquirer
|
|
559
542
|
const OUTPUT_DIR_FLAG_ACTIVE = !!outputDir
|
|
560
543
|
const presetId = preset || process.env.GENERATOR_PRESET
|
|
@@ -683,7 +666,7 @@ const main = async (opts) => {
|
|
|
683
666
|
}
|
|
684
667
|
|
|
685
668
|
// Generate the project.
|
|
686
|
-
runGenerator(context, {
|
|
669
|
+
runGenerator(context, {outputDir, templateVersion, verbose})
|
|
687
670
|
|
|
688
671
|
// Return the folder in which the project was generated in.
|
|
689
672
|
return outputDir
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|