@raisenow/tamaro-cli 1.1.8 → 1.2.0
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/.history/.eslintignore_20220609190420 +4 -0
- package/.history/.eslintignore_20230911190227 +6 -0
- package/.history/.eslintignore_20230911211247 +7 -0
- package/.history/.eslintignore_20230911211250 +7 -0
- package/.history/.eslintrc_20230911201601.js +49 -0
- package/.history/.eslintrc_20230911201643.js +49 -0
- package/.history/.eslintrc_20230911201735.js +49 -0
- package/.history/.eslintrc_20230911201913.js +64 -0
- package/.history/.eslintrc_20230911202002.js +62 -0
- package/.history/.eslintrc_20230911202138.js +133 -0
- package/.history/.eslintrc_20230911202140.js +133 -0
- package/.history/.eslintrc_20230911202145.js +133 -0
- package/.history/.eslintrc_20230911202147.js +133 -0
- package/.history/.eslintrc_20230911202406.js +133 -0
- package/.history/.eslintrc_20230911202447.js +133 -0
- package/.history/.eslintrc_20230911202453.js +133 -0
- package/.history/.eslintrc_20230911202511.js +133 -0
- package/.history/.eslintrc_20230911202527.js +133 -0
- package/.history/.eslintrc_20230911202639.js +125 -0
- package/.history/.eslintrc_20230911202721.js +149 -0
- package/.history/.eslintrc_20230911202746.js +149 -0
- package/.history/.eslintrc_20240423125702.cjs +148 -0
- package/.history/.gitignore_20220609190420 +14 -0
- package/.history/.gitignore_20230911185959 +4 -0
- package/.history/.gitignore_20230911190006 +4 -0
- package/.history/.gitignore_20230911190007 +4 -0
- package/.history/.nmprc_20241004144025 +0 -0
- package/.history/.nmprc_20241004144041 +1 -0
- package/.history/.npmrc_20241004144040 +1 -0
- package/.history/.npmrc_20241004144152 +1 -0
- package/.history/.npmrc_20241004145639 +2 -0
- package/.history/.npmrc_20241004145649 +1 -0
- package/.history/.nvmrc_20241125012803 +1 -0
- package/.history/.nvmrc_20241125022800 +1 -0
- package/.history/.nvmrc_20241125022806 +1 -0
- package/.history/.prettierignore_20220609190420 +5 -0
- package/.history/.prettierignore_20230911190242 +7 -0
- package/.history/.prettierignore_20230911190245 +7 -0
- package/.history/.prettierignore_20230911211301 +8 -0
- package/.history/CHANGELOG_20250624052910.md +20 -0
- package/.history/CHANGELOG_20250624055058.md +23 -0
- package/.history/CHANGELOG_20250624055107.md +23 -0
- package/.history/CHANGELOG_20250624055138.md +23 -0
- package/.history/CHANGELOG_20250624055156.md +23 -0
- package/.history/CHANGELOG_20250624055200.md +23 -0
- package/.history/CHANGELOG_20250624055203.md +23 -0
- package/.history/CHANGELOG_20250625142852.md +25 -0
- package/.history/CHANGELOG_20250625142901.md +22 -0
- package/.history/CHANGELOG_20250625142902.md +22 -0
- package/.history/README_20230911145033.md +245 -0
- package/.history/README_20230911151749.md +245 -0
- package/.history/README_20230911151844.md +245 -0
- package/.history/README_20230911153040.md +245 -0
- package/.history/README_20230911202959.md +245 -0
- package/.history/cli_20241005014539 +3 -0
- package/.history/cli_20241005014542 +3 -0
- package/.history/cli_20241005014848 +3 -0
- package/.history/dist/chunk-FICM3HUI_20230912183408.js +302 -0
- package/.history/dist/chunk-FICM3HUI_20230912201610.js +302 -0
- package/.history/package_20241107122123.json +106 -0
- package/.history/package_20241107122219.json +106 -0
- package/.history/package_20241107124611.json +106 -0
- package/.history/package_20241107125521.json +106 -0
- package/.history/package_20241107125538.json +106 -0
- package/.history/package_20241125013228.json +106 -0
- package/.history/package_20241125013249.json +106 -0
- package/.history/package_20241125014402.json +105 -0
- package/.history/package_20241125103106.json +105 -0
- package/.history/tsconfig_20241005001442.json +34 -0
- package/.history/tsconfig_20241005001500.json +34 -0
- package/.history/tsconfig_20241005001540.json +34 -0
- package/.history/tsconfig_20241005014429.json +42 -0
- package/.history/tsconfig_20241005014436.json +42 -0
- package/.history/tsconfig_20241005014439.json +38 -0
- package/.history/tsconfig_20241005014455.json +38 -0
- package/.idea/codeStyles/Project.xml +131 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/misc.xml +17 -0
- package/.idea/modules.xml +8 -0
- package/.idea/prettier.xml +6 -0
- package/.idea/tamaro-cli.iml +12 -0
- package/.idea/vcs.xml +6 -0
- package/README.md +35 -13
- package/bitbucket-pipelines.yml +43 -0
- package/dist/cli.js +42 -1
- package/dist/webpack.config.js +43 -12
- package/package.json +5 -1
- package/src/cli.ts +0 -178
- package/src/commands/build.ts +0 -131
- package/src/commands/deploy-email-config.ts +0 -159
- package/src/commands/deploy.ts +0 -164
- package/src/commands/dev.ts +0 -88
- package/src/commands/list-deployed.ts +0 -117
- package/src/commands/serve.ts +0 -69
- package/src/lib/InterpolateHtmlPlugin.ts +0 -47
- package/src/lib/aws.ts +0 -138
- package/src/lib/command.ts +0 -27
- package/src/lib/constants.ts +0 -9
- package/src/lib/env.ts +0 -175
- package/src/lib/https.ts +0 -27
- package/src/lib/logging.ts +0 -37
- package/src/lib/notifier.ts +0 -22
- package/src/lib/resolve.ts +0 -143
- package/src/webpack.config.ts +0 -437
- /package/{tsconfig.json → .history/tsconfig_20241005014521.json} +0 -0
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import {existsSync} from 'fs'
|
|
2
|
-
// eslint-disable-next-line import/no-named-as-default
|
|
3
|
-
import prompts from 'prompts'
|
|
4
|
-
import {
|
|
5
|
-
assertProfilesPresent,
|
|
6
|
-
assertProfileValid,
|
|
7
|
-
awsAuthenticate,
|
|
8
|
-
type AwsOptions,
|
|
9
|
-
prepareFlags,
|
|
10
|
-
promptProfile,
|
|
11
|
-
} from 'lib/aws'
|
|
12
|
-
import {halt, runCommandSync} from 'lib/command'
|
|
13
|
-
import {
|
|
14
|
-
AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD,
|
|
15
|
-
AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_STAGE,
|
|
16
|
-
} from 'lib/constants'
|
|
17
|
-
import {logCommand, logDataTable, logTitle} from 'lib/logging'
|
|
18
|
-
import {notify} from 'lib/notifier'
|
|
19
|
-
import {getIfCoreFns, getPaths, getWidgetUuid} from 'lib/resolve'
|
|
20
|
-
|
|
21
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
22
|
-
|
|
23
|
-
export type DeployEmailConfigOptions = AwsOptions & {
|
|
24
|
-
bucket?: string
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
28
|
-
|
|
29
|
-
export const deployEmailConfig = async (
|
|
30
|
-
options: DeployEmailConfigOptions,
|
|
31
|
-
): Promise<void> => {
|
|
32
|
-
const {ifCore} = getIfCoreFns()
|
|
33
|
-
const paths = getPaths(ifCore)
|
|
34
|
-
const emailConfigPath = `${paths.app}/email-config`
|
|
35
|
-
|
|
36
|
-
assertIsNotCore()
|
|
37
|
-
assertEmailConfigPathExists(emailConfigPath)
|
|
38
|
-
|
|
39
|
-
if (!options.profile && !options.ci) {
|
|
40
|
-
assertProfilesPresent()
|
|
41
|
-
options.profile = await promptProfile()
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (!options.bucket) {
|
|
45
|
-
options.bucket = options.ci
|
|
46
|
-
? AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD
|
|
47
|
-
: await promptBucketTamaroEmailConfig()
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
assertOptionsValid(options)
|
|
51
|
-
awsAuthenticate(options)
|
|
52
|
-
|
|
53
|
-
const flags = prepareFlags(options)
|
|
54
|
-
const configName = getWidgetUuid()
|
|
55
|
-
const deployUrl = `s3://${options.bucket}/${configName}`
|
|
56
|
-
|
|
57
|
-
const cmd = `
|
|
58
|
-
aws s3 sync ${emailConfigPath} ${deployUrl}
|
|
59
|
-
--delete
|
|
60
|
-
--exact-timestamps
|
|
61
|
-
${flags}
|
|
62
|
-
`
|
|
63
|
-
logTitle(
|
|
64
|
-
`Deploying email configuration for "${configName}" customer configuration to AWS S3 …`,
|
|
65
|
-
)
|
|
66
|
-
logCommand(cmd)
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
runCommandSync(cmd, {stdout: 'inherit'})
|
|
70
|
-
} catch (error: any) {
|
|
71
|
-
halt(error.stderr)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/////////////////////////////////////////////////////////////////////////////
|
|
75
|
-
|
|
76
|
-
logTitle(
|
|
77
|
-
`Email configuration for "${configName}" customer configuration is deployed.`,
|
|
78
|
-
)
|
|
79
|
-
logDataTable({'Deploy URL:': deployUrl})
|
|
80
|
-
|
|
81
|
-
/////////////////////////////////////////////////////////////////////////////
|
|
82
|
-
|
|
83
|
-
process.on('exit', () => {
|
|
84
|
-
notify({
|
|
85
|
-
title: 'deploy-email-config',
|
|
86
|
-
message: `Email configuration for "${configName}" customer configuration is deployed.`,
|
|
87
|
-
})
|
|
88
|
-
})
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
92
|
-
|
|
93
|
-
const assertOptionsValid = (options: DeployEmailConfigOptions) => {
|
|
94
|
-
const {profile, bucket} = options
|
|
95
|
-
|
|
96
|
-
if (profile) {
|
|
97
|
-
assertProfileValid(profile)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (bucket) {
|
|
101
|
-
assertBucketValid(bucket)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
106
|
-
|
|
107
|
-
const assertEmailConfigPathExists = (distPath: string) => {
|
|
108
|
-
if (!existsSync(distPath)) {
|
|
109
|
-
halt('Email config folder does not exists. Nothing to deploy.')
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
114
|
-
|
|
115
|
-
const assertIsNotCore = () => {
|
|
116
|
-
const {ifCore} = getIfCoreFns()
|
|
117
|
-
|
|
118
|
-
if (ifCore()) {
|
|
119
|
-
halt('You cannot deploy widget email configuration for Tamaro Core.')
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
124
|
-
|
|
125
|
-
const assertBucketValid = (bucket: string) => {
|
|
126
|
-
const buckets = [
|
|
127
|
-
AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_STAGE,
|
|
128
|
-
AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD,
|
|
129
|
-
] as const
|
|
130
|
-
|
|
131
|
-
if (!buckets.includes(bucket as any)) {
|
|
132
|
-
halt('Invalid bucket name.')
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
137
|
-
|
|
138
|
-
const promptBucketTamaroEmailConfig = async (): Promise<string> => {
|
|
139
|
-
const buckets = [
|
|
140
|
-
{title: 'stage', value: AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_STAGE},
|
|
141
|
-
{title: 'prod', value: AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD},
|
|
142
|
-
]
|
|
143
|
-
|
|
144
|
-
const {bucket} = await prompts(
|
|
145
|
-
[
|
|
146
|
-
{
|
|
147
|
-
type: 'select',
|
|
148
|
-
name: 'bucket',
|
|
149
|
-
message: 'Select environment',
|
|
150
|
-
choices: buckets,
|
|
151
|
-
},
|
|
152
|
-
],
|
|
153
|
-
{
|
|
154
|
-
onCancel: () => halt(),
|
|
155
|
-
},
|
|
156
|
-
)
|
|
157
|
-
|
|
158
|
-
return bucket
|
|
159
|
-
}
|
package/src/commands/deploy.ts
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import {existsSync} from 'fs'
|
|
2
|
-
import stripIndent from 'strip-indent'
|
|
3
|
-
import {
|
|
4
|
-
assertProfilesPresent,
|
|
5
|
-
assertProfileValid,
|
|
6
|
-
awsAuthenticate,
|
|
7
|
-
type AwsOptions,
|
|
8
|
-
prepareFlags,
|
|
9
|
-
promptProfile,
|
|
10
|
-
} from 'lib/aws'
|
|
11
|
-
import {halt, runCommandSync} from 'lib/command'
|
|
12
|
-
import {
|
|
13
|
-
AWS_CLOUDFRONT_DISTRIBUTION_ID,
|
|
14
|
-
AWS_S3_BUCKET_TAMARO,
|
|
15
|
-
CORE_CONFIG_NAME,
|
|
16
|
-
} from 'lib/constants'
|
|
17
|
-
import {logCommand, logDataTable, logTitle} from 'lib/logging'
|
|
18
|
-
import {notify} from 'lib/notifier'
|
|
19
|
-
import {getIfCoreFns, getPaths, getWidgetUuid} from 'lib/resolve'
|
|
20
|
-
|
|
21
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
22
|
-
|
|
23
|
-
export type DeployOptions = AwsOptions & {
|
|
24
|
-
tag: string
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
28
|
-
|
|
29
|
-
export const deploy = async (options: DeployOptions): Promise<void> => {
|
|
30
|
-
const {ifCore} = getIfCoreFns()
|
|
31
|
-
const paths = getPaths(ifCore)
|
|
32
|
-
|
|
33
|
-
assertDistPathExists(paths.appDist)
|
|
34
|
-
|
|
35
|
-
if (!options.profile && !options.ci) {
|
|
36
|
-
assertProfilesPresent()
|
|
37
|
-
options.profile = await promptProfile()
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
assertOptionsValid(options)
|
|
41
|
-
awsAuthenticate(options)
|
|
42
|
-
|
|
43
|
-
const flags = prepareFlags(options)
|
|
44
|
-
const {tag} = options
|
|
45
|
-
const configName = ifCore(CORE_CONFIG_NAME, getWidgetUuid())
|
|
46
|
-
const deployUrl = `s3://${AWS_S3_BUCKET_TAMARO}/${configName}/${tag}`
|
|
47
|
-
const entryFilename = ifCore('index.js', 'widget.js')
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Sync all files except entrypoint (without deleting old files)
|
|
51
|
-
*/
|
|
52
|
-
const cmdSyncAll = `
|
|
53
|
-
aws s3 sync ${paths.appDist} ${deployUrl}
|
|
54
|
-
--acl public-read
|
|
55
|
-
--exclude ${paths.appDist}/${entryFilename}
|
|
56
|
-
--cache-control max-age=31536000
|
|
57
|
-
${flags}
|
|
58
|
-
`
|
|
59
|
-
logTitle('Deploying to AWS S3 …')
|
|
60
|
-
logCommand(cmdSyncAll)
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
runCommandSync(cmdSyncAll, {stdout: 'inherit'})
|
|
64
|
-
} catch (error: any) {
|
|
65
|
-
halt(error.stderr)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Copy entrypoint
|
|
70
|
-
*/
|
|
71
|
-
const cmdCpEntry = `
|
|
72
|
-
aws s3 cp ${paths.appDist}/${entryFilename} ${deployUrl}/${entryFilename}
|
|
73
|
-
--acl public-read
|
|
74
|
-
--cache-control max-age=64800
|
|
75
|
-
${flags}
|
|
76
|
-
`
|
|
77
|
-
logCommand(cmdCpEntry)
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
runCommandSync(cmdCpEntry, {stdout: 'inherit'})
|
|
81
|
-
} catch (error: any) {
|
|
82
|
-
halt(error.stderr)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Invalidate cloudfront cache
|
|
87
|
-
*/
|
|
88
|
-
const cmdInvalidateCache = `
|
|
89
|
-
aws cloudfront create-invalidation
|
|
90
|
-
--distribution-id ${AWS_CLOUDFRONT_DISTRIBUTION_ID}
|
|
91
|
-
--paths /${configName}/${tag}/*
|
|
92
|
-
${flags}
|
|
93
|
-
`
|
|
94
|
-
logTitle('\nInvalidating edge cache …')
|
|
95
|
-
logCommand(cmdInvalidateCache)
|
|
96
|
-
|
|
97
|
-
try {
|
|
98
|
-
// ignore output
|
|
99
|
-
runCommandSync(cmdInvalidateCache)
|
|
100
|
-
} catch (error: any) {
|
|
101
|
-
halt(error.stderr)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/////////////////////////////////////////////////////////////////////////////
|
|
105
|
-
|
|
106
|
-
const demoPage = `https://${AWS_S3_BUCKET_TAMARO}/${configName}/${tag}/index.html`
|
|
107
|
-
const entryPoint = `https://${AWS_S3_BUCKET_TAMARO}/${configName}/${tag}/${entryFilename}`
|
|
108
|
-
|
|
109
|
-
logTitle(`\nBundle for "${configName}" is deployed with tag "${tag}".`)
|
|
110
|
-
logDataTable({
|
|
111
|
-
'Demo page:': demoPage,
|
|
112
|
-
'Entry point:': entryPoint,
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
/////////////////////////////////////////////////////////////////////////////
|
|
116
|
-
|
|
117
|
-
process.on('exit', () => {
|
|
118
|
-
notify({
|
|
119
|
-
title: 'deploy',
|
|
120
|
-
message: `
|
|
121
|
-
Bundle for "${configName}" is deployed with tag "${tag}".
|
|
122
|
-
Demo page: ${demoPage}
|
|
123
|
-
Entry point: ${entryPoint}
|
|
124
|
-
`,
|
|
125
|
-
})
|
|
126
|
-
})
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
130
|
-
|
|
131
|
-
const assertOptionsValid = (options: DeployOptions) => {
|
|
132
|
-
const {profile, tag} = options
|
|
133
|
-
|
|
134
|
-
if (profile) {
|
|
135
|
-
assertProfileValid(profile)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
assertTagValid(tag)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
142
|
-
|
|
143
|
-
const assertDistPathExists = (distPath: string) => {
|
|
144
|
-
if (!existsSync(distPath)) {
|
|
145
|
-
halt(
|
|
146
|
-
stripIndent(`
|
|
147
|
-
Dist folder does not exists.
|
|
148
|
-
Make sure you have built the bundle before trying to deploy it.
|
|
149
|
-
`),
|
|
150
|
-
)
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
155
|
-
|
|
156
|
-
const assertTagValid = (tag: string) => {
|
|
157
|
-
const regex = /^[a-zA-Z0-9-_.]+$/
|
|
158
|
-
|
|
159
|
-
if (!regex.test(tag)) {
|
|
160
|
-
halt(
|
|
161
|
-
`Flag "--tag" has forbidden format. Allowed format: ${regex.toString()}.`,
|
|
162
|
-
)
|
|
163
|
-
}
|
|
164
|
-
}
|
package/src/commands/dev.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import {getPortPromise} from 'portfinder'
|
|
2
|
-
import {halt, runCommandSync} from 'lib/command'
|
|
3
|
-
import {applyEnv, assertEnvValid} from 'lib/env'
|
|
4
|
-
import {assertCrtExists} from 'lib/https'
|
|
5
|
-
import {logCommand, logTitle} from 'lib/logging'
|
|
6
|
-
import {getIfCoreFns, resolveBin, resolveOwn} from 'lib/resolve'
|
|
7
|
-
|
|
8
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
9
|
-
|
|
10
|
-
export type DevOptions = {
|
|
11
|
-
localCore: boolean
|
|
12
|
-
https: boolean
|
|
13
|
-
port: string
|
|
14
|
-
env?: string
|
|
15
|
-
nolint: boolean
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
19
|
-
|
|
20
|
-
export const dev = async (options: DevOptions): Promise<void> => {
|
|
21
|
-
const {env} = options
|
|
22
|
-
|
|
23
|
-
applyEnv(env)
|
|
24
|
-
assertOptionsValid(options)
|
|
25
|
-
|
|
26
|
-
const flags = await prepareFlags(options)
|
|
27
|
-
const {ifCore} = getIfCoreFns()
|
|
28
|
-
const title = ifCore(
|
|
29
|
-
'Running dev web-server for Tamaro Core …',
|
|
30
|
-
'Running dev web-server for customer configuration …',
|
|
31
|
-
)
|
|
32
|
-
const wpBin = resolveBin('webpack')
|
|
33
|
-
const wpConfig = resolveOwn('dist/webpack.config.js')
|
|
34
|
-
const cmd = `
|
|
35
|
-
${wpBin} serve
|
|
36
|
-
--config ${wpConfig}
|
|
37
|
-
${flags}
|
|
38
|
-
`
|
|
39
|
-
|
|
40
|
-
logTitle(title)
|
|
41
|
-
logCommand(cmd)
|
|
42
|
-
runCommandSync(cmd, {stdio: 'inherit'})
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
46
|
-
|
|
47
|
-
const assertOptionsValid = (options: DevOptions) => {
|
|
48
|
-
const {localCore, https, port, env} = options
|
|
49
|
-
const {ifCore} = getIfCoreFns()
|
|
50
|
-
|
|
51
|
-
if (ifCore() && localCore) {
|
|
52
|
-
halt('Flag "--local-core" is redundant if running in Tamaro Core context.')
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (isNaN(Number(port))) {
|
|
56
|
-
halt('Flag "--port" should be a number.')
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (https) {
|
|
60
|
-
assertCrtExists()
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
assertEnvValid(env)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
67
|
-
|
|
68
|
-
const prepareFlags = async (options: DevOptions) => {
|
|
69
|
-
const flags: string[] = []
|
|
70
|
-
const {localCore, port: defaultPort, https, nolint} = options
|
|
71
|
-
const port = await getPortPromise({port: Number(defaultPort)})
|
|
72
|
-
|
|
73
|
-
if (localCore) {
|
|
74
|
-
flags.push('--env localCore')
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
flags.push(`--port ${port}`)
|
|
78
|
-
|
|
79
|
-
if (https) {
|
|
80
|
-
flags.push('--env https')
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (nolint) {
|
|
84
|
-
flags.push('--env nolint')
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return flags.join(' ')
|
|
88
|
-
}
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
assertProfilesPresent,
|
|
3
|
-
assertProfileValid,
|
|
4
|
-
awsAuthenticate,
|
|
5
|
-
type AwsOptions,
|
|
6
|
-
prepareFlags,
|
|
7
|
-
promptProfile,
|
|
8
|
-
} from 'lib/aws'
|
|
9
|
-
import {halt, runCommandSync} from 'lib/command'
|
|
10
|
-
import {AWS_S3_BUCKET_TAMARO, CORE_CONFIG_NAME} from 'lib/constants'
|
|
11
|
-
import {logCommand, logTitle} from 'lib/logging'
|
|
12
|
-
import {getIfCoreFns, getWidgetUuid} from 'lib/resolve'
|
|
13
|
-
|
|
14
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
15
|
-
|
|
16
|
-
export type ListDeployedOptions = AwsOptions & {
|
|
17
|
-
config?: string
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
21
|
-
|
|
22
|
-
export const listDeployed = async (
|
|
23
|
-
options: ListDeployedOptions,
|
|
24
|
-
): Promise<void> => {
|
|
25
|
-
if (!options.profile && !options.ci) {
|
|
26
|
-
assertProfilesPresent()
|
|
27
|
-
options.profile = await promptProfile()
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
assertOptionsValid(options)
|
|
31
|
-
awsAuthenticate(options)
|
|
32
|
-
|
|
33
|
-
const flags = prepareFlags(options)
|
|
34
|
-
const {config} = options
|
|
35
|
-
const {ifCore} = getIfCoreFns()
|
|
36
|
-
const configName = config ?? ifCore(CORE_CONFIG_NAME, getWidgetUuid())
|
|
37
|
-
const title =
|
|
38
|
-
!config && ifCore()
|
|
39
|
-
? `Listing deployments of Tamaro Core …`
|
|
40
|
-
: `Listing deployments of "${configName}" customer configuration …`
|
|
41
|
-
|
|
42
|
-
const deployUrl = `s3://${AWS_S3_BUCKET_TAMARO}/${configName}/`
|
|
43
|
-
const cmd = `aws s3 ls ${deployUrl} ${flags}`
|
|
44
|
-
let out = ''
|
|
45
|
-
|
|
46
|
-
logTitle(title)
|
|
47
|
-
logCommand(cmd)
|
|
48
|
-
|
|
49
|
-
// If customer configuration folder does not exist on AWS S3,
|
|
50
|
-
// command fails with blank stderr, so we need to handle this case.
|
|
51
|
-
try {
|
|
52
|
-
const result = runCommandSync(cmd)
|
|
53
|
-
out = result.stdout as string
|
|
54
|
-
} catch (error: any) {
|
|
55
|
-
out = error.stdout as string
|
|
56
|
-
|
|
57
|
-
if (error.stderr) {
|
|
58
|
-
halt(error.stderr)
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const lines = out.split('\n')
|
|
63
|
-
const tags = parseTags(lines)
|
|
64
|
-
let text = ''
|
|
65
|
-
|
|
66
|
-
if (tags.length === 0) {
|
|
67
|
-
text = 'No deployments found.'
|
|
68
|
-
} else {
|
|
69
|
-
text = tags
|
|
70
|
-
.map((tag, idx) => {
|
|
71
|
-
// prettier-ignore
|
|
72
|
-
return `${idx + 1}. https://${AWS_S3_BUCKET_TAMARO}/${configName}/${tag}/index.html`
|
|
73
|
-
})
|
|
74
|
-
.join('\n')
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// eslint-disable-next-line no-console
|
|
78
|
-
console.log(`${text}\n`)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
82
|
-
|
|
83
|
-
const assertOptionsValid = (options: ListDeployedOptions) => {
|
|
84
|
-
const {config, profile} = options
|
|
85
|
-
|
|
86
|
-
assertConfigValid(config)
|
|
87
|
-
|
|
88
|
-
if (profile) {
|
|
89
|
-
assertProfileValid(profile)
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
94
|
-
|
|
95
|
-
const assertConfigValid = (config: string | undefined) => {
|
|
96
|
-
if (!config) {
|
|
97
|
-
return
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const regex = /^[a-zA-Z0-9-_]+$/
|
|
101
|
-
|
|
102
|
-
if (!regex.test(config)) {
|
|
103
|
-
halt(
|
|
104
|
-
`Flag "--config" has forbidden format. Allowed format: ${regex.toString()}.`,
|
|
105
|
-
)
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
110
|
-
|
|
111
|
-
const parseTags = (lines: string[]): string[] => {
|
|
112
|
-
const regex = /^\s*PRE\s*/
|
|
113
|
-
|
|
114
|
-
return lines
|
|
115
|
-
.filter((line) => regex.test(line))
|
|
116
|
-
.map((line) => line.replace(regex, '').replace(/\/$/, ''))
|
|
117
|
-
}
|
package/src/commands/serve.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import {resolve} from 'path'
|
|
2
|
-
import {getPortPromise} from 'portfinder'
|
|
3
|
-
import {halt, runCommandSync} from 'lib/command'
|
|
4
|
-
import {HTTPS_CRT_FILE, HTTPS_KEY_FILE} from 'lib/constants'
|
|
5
|
-
import {assertCrtExists} from 'lib/https'
|
|
6
|
-
import {logCommand, logTitle} from 'lib/logging'
|
|
7
|
-
import {getIfCoreFns, getPaths} from 'lib/resolve'
|
|
8
|
-
|
|
9
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
10
|
-
|
|
11
|
-
export type ServeOptions = {
|
|
12
|
-
port: string
|
|
13
|
-
https: boolean
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
17
|
-
|
|
18
|
-
export const serve = async (options: ServeOptions): Promise<void> => {
|
|
19
|
-
assertOptionsValid(options)
|
|
20
|
-
|
|
21
|
-
const flags = await prepareFlags(options)
|
|
22
|
-
const {ifCore} = getIfCoreFns()
|
|
23
|
-
const paths = getPaths(ifCore)
|
|
24
|
-
const cmd = `
|
|
25
|
-
npx -y serve ${paths.appDist}
|
|
26
|
-
--cors
|
|
27
|
-
${flags}
|
|
28
|
-
`
|
|
29
|
-
|
|
30
|
-
logTitle(`Running web-server for pre-built bundle …`)
|
|
31
|
-
logCommand(cmd)
|
|
32
|
-
runCommandSync(cmd, {stdio: 'inherit'})
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
36
|
-
|
|
37
|
-
const assertOptionsValid = (options: ServeOptions) => {
|
|
38
|
-
const {port, https} = options
|
|
39
|
-
|
|
40
|
-
if (isNaN(Number(port))) {
|
|
41
|
-
halt('Flag "--port" should be a number.')
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (https) {
|
|
45
|
-
assertCrtExists()
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
50
|
-
|
|
51
|
-
const prepareFlags = async (options: ServeOptions) => {
|
|
52
|
-
const flags: string[] = []
|
|
53
|
-
const {port: defaultPort, https} = options
|
|
54
|
-
const port = await getPortPromise({port: Number(defaultPort)})
|
|
55
|
-
|
|
56
|
-
flags.push(`-p ${port}`)
|
|
57
|
-
|
|
58
|
-
if (https) {
|
|
59
|
-
const {ifCore} = getIfCoreFns()
|
|
60
|
-
const paths = getPaths(ifCore)
|
|
61
|
-
const certFile = resolve(paths.root, HTTPS_CRT_FILE)
|
|
62
|
-
const keyFile = resolve(paths.root, HTTPS_KEY_FILE)
|
|
63
|
-
|
|
64
|
-
flags.push(`--ssl-cert ${certFile}`)
|
|
65
|
-
flags.push(`--ssl-key ${keyFile}`)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return flags.join(' ')
|
|
69
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import escapeStringRegexp from 'escape-string-regexp'
|
|
2
|
-
import HtmlWebpackPlugin from 'html-webpack-plugin'
|
|
3
|
-
import {type Compiler} from 'webpack'
|
|
4
|
-
|
|
5
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
6
|
-
|
|
7
|
-
export type Replacements = Record<string, string | undefined>
|
|
8
|
-
|
|
9
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
10
|
-
|
|
11
|
-
const PLUGIN_NAME = 'InterpolateHtmlPlugin'
|
|
12
|
-
|
|
13
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
14
|
-
|
|
15
|
-
export class InterpolateHtmlPlugin {
|
|
16
|
-
replacements: Replacements
|
|
17
|
-
|
|
18
|
-
constructor(replacements: Replacements) {
|
|
19
|
-
this.replacements = {...replacements}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
apply(compiler: Compiler): void {
|
|
23
|
-
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
24
|
-
const hooks = HtmlWebpackPlugin.getHooks(compilation)
|
|
25
|
-
|
|
26
|
-
hooks.alterAssetTagGroups.tap(PLUGIN_NAME, (assets) => {
|
|
27
|
-
const publicUrl = this.replacements.PUBLIC_URL ?? ''
|
|
28
|
-
const entry = assets.headTags[0].attributes.src as string
|
|
29
|
-
this.replacements.ENTRY = `${publicUrl}${entry}`
|
|
30
|
-
|
|
31
|
-
return assets
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
hooks.afterTemplateExecution.tap(PLUGIN_NAME, (data) => {
|
|
35
|
-
// Run HTML through a series of user-specified string replacements.
|
|
36
|
-
Object.entries(this.replacements).forEach(([key, value]) => {
|
|
37
|
-
data.html = data.html.replace(
|
|
38
|
-
new RegExp(`%${escapeStringRegexp(key)}%`, 'g'),
|
|
39
|
-
value ?? '',
|
|
40
|
-
)
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
return data
|
|
44
|
-
})
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
}
|