@raisenow/tamaro-cli 1.0.9 → 1.0.12

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/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@raisenow/tamaro-cli",
3
- "version": "1.0.9",
3
+ "version": "1.0.12",
4
4
  "author": {
5
5
  "name": "RaiseNow",
6
6
  "email": "development@raisenow.com"
7
7
  },
8
- "main": "dist/cli.js",
8
+ "type": "module",
9
9
  "scripts": {
10
10
  "prepare": "npm run build",
11
11
  "start": "npm run dev",
12
- "dev": "npm run build -- --watch --ignore-watch .idea",
13
- "build": "tsup src/cli.ts src/webpack.config.ts --format cjs",
12
+ "build": "tsup src/cli.ts src/webpack.config.ts --clean --format esm",
13
+ "build:watch": "npm run build -- --watch --ignore-watch .idea",
14
14
  "docs": "npx -y http-server . --cors -o /readme.html",
15
15
  "lint": "eslint . --fix && prettier --write ."
16
16
  },
@@ -20,78 +20,72 @@
20
20
  "npm": ">=8"
21
21
  },
22
22
  "dependencies": {
23
- "@babel/cli": "^7.17.0",
24
- "@babel/core": "^7.17.0",
25
- "@babel/plugin-proposal-decorators": "^7.17.0",
23
+ "@babel/cli": "^7.17.6",
24
+ "@babel/core": "^7.17.8",
25
+ "@babel/plugin-proposal-decorators": "^7.17.8",
26
26
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
27
27
  "@babel/plugin-transform-runtime": "^7.17.0",
28
28
  "@babel/preset-env": "^7.16.11",
29
29
  "@babel/preset-react": "^7.16.7",
30
30
  "@babel/preset-typescript": "^7.16.7",
31
- "@babel/runtime-corejs3": "^7.17.0",
31
+ "@babel/runtime-corejs3": "^7.17.8",
32
32
  "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4",
33
33
  "@statoscope/webpack-plugin": "^5.20.1",
34
34
  "@svgr/webpack": "^6.2.1",
35
35
  "@types/columnify": "^1.5.1",
36
- "@types/lodash": "^4.14.178",
37
- "@types/mini-css-extract-plugin": "^2.5.1",
38
- "@types/node": "^17.0.16",
36
+ "@types/lodash": "^4.14.180",
37
+ "@types/node": "^17.0.21",
39
38
  "@types/node-notifier": "^8.0.2",
40
39
  "@types/resolve-bin": "^0.4.1",
41
40
  "@types/webpack-config-utils": "^2.3.1",
42
- "@typescript-eslint/eslint-plugin": "^5.11.0",
43
- "@typescript-eslint/parser": "^5.11.0",
44
- "autoprefixer": "^10.4.2",
41
+ "@typescript-eslint/eslint-plugin": "^5.15.0",
42
+ "@typescript-eslint/parser": "^5.15.0",
43
+ "autoprefixer": "^10.4.4",
45
44
  "babel-loader": "^8.2.3",
46
45
  "babel-plugin-lodash": "^3.3.4",
47
- "boxen": "^5.1.2",
48
- "chalk": "^4.1.2",
46
+ "chalk": "^5.0.1",
49
47
  "clean-webpack-plugin": "^4.0.0",
50
48
  "columnify": "^1.6.0",
51
- "commander": "^9.0.0",
49
+ "commander": "^9.1.0",
52
50
  "copy-webpack-plugin": "^10.2.4",
53
- "core-js": "^3.21.0",
54
- "css-loader": "^6.6.0",
51
+ "core-js": "^3.21.1",
52
+ "css-loader": "^6.7.1",
55
53
  "css-minimizer-webpack-plugin": "^3.4.1",
56
- "current-script-polyfill": "^1.0.0",
57
54
  "dotenv": "^16.0.0",
58
- "dotenv-expand": "^8.0.1",
59
- "element-closest": "^3.0.2",
60
- "escape-string-regexp": "^4.0.0",
61
- "eslint": "^8.8.0",
55
+ "dotenv-expand": "^8.0.3",
56
+ "escape-string-regexp": "^5.0.0",
57
+ "eslint": "^8.11.0",
58
+ "eslint-config-prettier": "^8.5.0",
62
59
  "eslint-plugin-node": "^11.1.0",
63
60
  "eslint-plugin-promise": "^6.0.0",
64
- "eslint-webpack-plugin": "^3.1.0",
65
- "execa": "^5.1.1",
61
+ "eslint-webpack-plugin": "^3.1.1",
62
+ "execa": "^6.1.0",
66
63
  "file-loader": "^6.2.0",
67
- "fork-ts-checker-webpack-plugin": "^7.1.1",
64
+ "fork-ts-checker-webpack-plugin": "^7.2.1",
68
65
  "glob": "^7.2.0",
69
66
  "html-loader": "^3.1.0",
70
67
  "html-webpack-plugin": "^5.5.0",
71
68
  "json-loader": "^0.5.7",
72
69
  "lodash": "^4.17.21",
73
- "mini-css-extract-plugin": "^2.5.3",
70
+ "mini-css-extract-plugin": "^2.6.0",
74
71
  "node-notifier": "^10.0.1",
75
- "open": "^8.4.0",
76
72
  "portfinder": "^1.0.28",
77
- "postcss": "^8.4.6",
78
- "postcss-custom-properties": "^12.1.4",
73
+ "postcss": "^8.4.12",
74
+ "postcss-custom-properties": "^12.1.5",
79
75
  "postcss-loader": "^6.2.1",
80
- "prettier": "^2.5.1",
76
+ "prettier": "^2.6.0",
81
77
  "react-refresh": "^0.11.0",
82
- "resolve-bin": "^1.0.0",
83
78
  "resolve-url-loader": "^5.0.0",
84
- "sass": "^1.49.7",
85
- "sass-loader": "^12.4.0",
79
+ "sass": "^1.49.9",
80
+ "sass-loader": "^12.6.0",
86
81
  "source-map-loader": "^3.0.1",
87
- "strip-indent": "^3.0.0",
82
+ "strip-indent": "^4.0.0",
88
83
  "style-loader": "^3.3.1",
89
84
  "tsconfig-paths-webpack-plugin": "^3.5.2",
90
- "tsup": "^5.11.13",
91
- "typescript": "^4.5.5",
92
- "unfetch": "^4.2.0",
85
+ "tsup": "^5.12.1",
86
+ "typescript": "^4.6.2",
93
87
  "url-loader": "^4.1.1",
94
- "webpack": "^5.68.0",
88
+ "webpack": "^5.70.0",
95
89
  "webpack-cli": "^4.9.2",
96
90
  "webpack-config-utils": "^2.3.1",
97
91
  "webpack-dev-server": "^4.7.4",
package/readme.html CHANGED
@@ -40,7 +40,7 @@
40
40
  name: '@raisenow/tamaro-cli',
41
41
  // themeColor: '#537397',
42
42
  maxLevel: 2,
43
- homepage: './readme.md',
43
+ homepage: './README.md',
44
44
  coverpage: false,
45
45
  }
46
46
  </script>
package/src/cli.ts CHANGED
@@ -2,18 +2,22 @@
2
2
 
3
3
  import {createCommand} from 'commander'
4
4
  import pkg from '../package.json'
5
- import {logError} from 'lib/helpers'
5
+ import {
6
+ DEFAULT_AWS_PROFILE,
7
+ DEFAULT_AWS_S3_EMAIL_CONFIG_BUCKET,
8
+ DEFAULT_PORT,
9
+ DEFAULT_TAG,
10
+ } from 'lib/constants'
11
+ import {logError} from 'lib/logging'
6
12
  import {dev, DevOptions} from 'commands/dev'
7
13
  import {build, BuildOptions} from 'commands/build'
8
- import {DEFAULT_TAG, deploy, DeployOptions} from 'commands/deploy'
9
- import {serve} from 'commands/serve'
14
+ import {deploy, DeployOptions} from 'commands/deploy'
15
+ import {serve, ServeOptions} from 'commands/serve'
10
16
  import {listDeployed, ListDeployedOptions} from 'commands/list-deployed'
11
17
  import {
12
- DEFAULT_AWS_S3_EMAIL_CONFIG_BUCKET,
13
18
  deployEmailConfig,
14
19
  DeployEmailConfigOptions,
15
20
  } from 'commands/deploy-email-config'
16
- import {DEFAULT_AWS_PROFILE} from 'lib/aws'
17
21
 
18
22
  ///////////////////////////////////////////////////////////////////////////////
19
23
 
@@ -42,9 +46,10 @@ cli
42
46
  )
43
47
  .option(
44
48
  '--local-core',
45
- 'Load Tamaro Core from localhost instead of the CDN',
49
+ 'Load Tamaro Core from localhost:1234 instead of the CDN',
46
50
  false,
47
51
  )
52
+ .option('--port <port>', 'Web server port', `${DEFAULT_PORT}`)
48
53
  .action(async (options: DevOptions) => {
49
54
  await dev(options)
50
55
  })
@@ -56,16 +61,17 @@ cli
56
61
  )
57
62
  .option(
58
63
  '--local-core',
59
- 'Load Tamaro Core from localhost instead of the CDN',
64
+ 'Load Tamaro Core from localhost:1234 instead of the CDN',
60
65
  false,
61
66
  )
62
67
  .option('--analyze', 'Generate bundle statistics to "reports" folder', false)
68
+ .option('--serve', 'Run the generated bundle with a local web server', false)
69
+ .option('--port <port>', 'Web server port', `${DEFAULT_PORT}`)
63
70
  .option(
64
71
  '--deploy',
65
72
  'Deploy Tamaro Core or a customer configuration bundle to AWS S3',
66
73
  false,
67
74
  )
68
- .option('--serve', 'Run the generated bundle with a local web server', false)
69
75
  .option(
70
76
  '--tag <tag>',
71
77
  'Tag which should be used for the deployment of the bundle',
@@ -76,16 +82,24 @@ cli
76
82
  'AWS profile which should be used for the deployment of the bundle',
77
83
  DEFAULT_AWS_PROFILE,
78
84
  )
79
- .action(async (options: BuildOptions & DeployOptions) => {
85
+ .action(async (options: BuildOptions & ServeOptions & DeployOptions) => {
80
86
  await build(options)
81
87
 
88
+ if (options.serve) {
89
+ await serve(options)
90
+ }
91
+
82
92
  if (options.deploy) {
83
93
  await deploy(options)
84
94
  }
95
+ })
85
96
 
86
- if (options.serve) {
87
- await serve()
88
- }
97
+ cli
98
+ .command('serve')
99
+ .description('Run a local web server for pre-built bundle')
100
+ .option('--port <port>', 'Web server port', `${DEFAULT_PORT}`)
101
+ .action(async (options: ServeOptions) => {
102
+ await serve(options)
89
103
  })
90
104
 
91
105
  cli
@@ -107,13 +121,6 @@ cli
107
121
  await deploy(options)
108
122
  })
109
123
 
110
- cli
111
- .command('serve')
112
- .description('Run a local web server for pre-built bundle')
113
- .action(async () => {
114
- await serve()
115
- })
116
-
117
124
  cli
118
125
  .command('list-deployed')
119
126
  .description(
@@ -156,6 +163,9 @@ cli
156
163
  } catch (error: any) {
157
164
  if (error.signal === 'SIGINT' && error.signalDescription) {
158
165
  logError(`\n${error.signalDescription}`)
166
+ } else {
167
+ console.log('')
168
+ logError(error.stack)
159
169
  }
160
170
  }
161
171
  })()
@@ -1,26 +1,24 @@
1
- import resolveBin from 'resolve-bin'
1
+ import {CORE_CONFIG_NAME} from 'lib/constants'
2
+ import {assertProfileValid} from 'lib/aws'
2
3
  import {
3
- fail,
4
4
  getIfCoreFns,
5
5
  getPaths,
6
6
  getWidgetUuid,
7
- logCommand,
8
- logDataTable,
9
- logTitle,
10
- notify,
7
+ resolveBin,
11
8
  resolveOwn,
12
- runCommandSync,
13
- } from 'lib/helpers'
14
- import {assertProfileValid} from 'lib/aws'
15
- import {CORE_CONFIG_NAME, DeployOptions} from 'commands/deploy'
9
+ } from 'lib/resolve'
10
+ import {logCommand, logTitle} from 'lib/logging'
11
+ import {notify} from 'lib/notifier'
12
+ import {fail, runCommandSync} from 'lib/command'
13
+ import {DeployOptions} from 'commands/deploy'
16
14
 
17
15
  ///////////////////////////////////////////////////////////////////////////////
18
16
 
19
17
  export type BuildOptions = {
20
18
  localCore: boolean
21
19
  analyze: boolean
22
- deploy: boolean
23
20
  serve: boolean
21
+ deploy: boolean
24
22
  }
25
23
 
26
24
  ///////////////////////////////////////////////////////////////////////////////
@@ -30,7 +28,7 @@ export const build = async (
30
28
  ): Promise<void> => {
31
29
  assertOptionsValid(options)
32
30
 
33
- const flags = prepareFlags(options)
31
+ const flags = prepareFlags([], options).join(' ')
34
32
  const {ifCore} = getIfCoreFns()
35
33
  const paths = getPaths(ifCore)
36
34
  const configName = ifCore(CORE_CONFIG_NAME, getWidgetUuid())
@@ -39,7 +37,7 @@ export const build = async (
39
37
  `Building optimised (minified) bundle of “${configName}” customer configuration …`,
40
38
  )
41
39
 
42
- const wpBin = resolveBin.sync('webpack')
40
+ const wpBin = resolveBin('webpack')
43
41
  const wpConfig = resolveOwn('dist/webpack.config.js')
44
42
  const cmd = `
45
43
  ${wpBin}
@@ -54,16 +52,16 @@ export const build = async (
54
52
 
55
53
  /////////////////////////////////////////////////////////////////////////////
56
54
 
57
- logDataTable(
58
- {'Path:': paths.appDist},
59
- `Bundle for “${configName}” customer configuration is done.`,
60
- )
55
+ logTitle(`\nBundle for “${configName}” customer configuration is done.`)
56
+ console.log(`Path: ${paths.appDist}\n`)
61
57
 
62
58
  /////////////////////////////////////////////////////////////////////////////
63
59
 
64
- notify({
65
- title: 'build',
66
- message: `Bundle for “${configName}” customer configuration is done.`,
60
+ process.on('exit', () => {
61
+ notify({
62
+ title: 'build',
63
+ message: `Bundle for “${configName}” customer configuration is done.`,
64
+ })
67
65
  })
68
66
  }
69
67
 
@@ -86,12 +84,16 @@ const assertOptionsValid = (options: BuildOptions & DeployOptions) => {
86
84
 
87
85
  ///////////////////////////////////////////////////////////////////////////////
88
86
 
89
- const prepareFlags = (options: BuildOptions): string => {
87
+ const prepareFlags = (flags: string[], options: BuildOptions): string[] => {
90
88
  const {localCore, analyze} = options
91
- let flags: string[] = []
92
89
 
93
- flags = localCore ? [...flags, '--env localCore'] : flags
94
- flags = analyze ? [...flags, '--env analyze'] : flags
90
+ if (localCore) {
91
+ flags.push('--env localCore')
92
+ }
93
+
94
+ if (analyze) {
95
+ flags.push('--env analyze')
96
+ }
95
97
 
96
- return flags.join(' ')
98
+ return flags
97
99
  }
@@ -1,15 +1,14 @@
1
1
  import {existsSync} from 'fs'
2
2
  import {
3
- fail,
4
- getIfCoreFns,
5
- getPaths,
6
- getWidgetUuid,
7
- logCommand,
8
- logDataTable,
9
- logTitle,
10
- notify,
11
- } from 'lib/helpers'
12
- import {assertProfileValid, AwsOptions, runAwsCommandSync} from 'lib/aws'
3
+ assertProfileValid,
4
+ AwsOptions,
5
+ withAwsAuthenticate,
6
+ prepareFlags as prepareAwsFlags,
7
+ } from 'lib/aws'
8
+ import {logCommand, logDataTable, logTitle} from 'lib/logging'
9
+ import {getIfCoreFns, getPaths, getWidgetUuid} from 'lib/resolve'
10
+ import {notify} from 'lib/notifier'
11
+ import {fail, runCommandSync} from 'lib/command'
13
12
 
14
13
  ///////////////////////////////////////////////////////////////////////////////
15
14
 
@@ -19,10 +18,6 @@ export type DeployEmailConfigOptions = AwsOptions & {
19
18
 
20
19
  ///////////////////////////////////////////////////////////////////////////////
21
20
 
22
- export const DEFAULT_AWS_S3_EMAIL_CONFIG_BUCKET = 'rnw-email-service'
23
-
24
- ///////////////////////////////////////////////////////////////////////////////
25
-
26
21
  export const deployEmailConfig = async (
27
22
  options: DeployEmailConfigOptions,
28
23
  ): Promise<void> => {
@@ -34,6 +29,7 @@ export const deployEmailConfig = async (
34
29
  assertEmailConfigPathExists(emailConfigPath)
35
30
  assertIsNotCore()
36
31
 
32
+ const flags = prepareFlags([], options).join(' ')
37
33
  const {bucket} = options
38
34
  const configName = getWidgetUuid()
39
35
  const deployUrl = `s3://${bucket}/${configName}`
@@ -42,6 +38,7 @@ export const deployEmailConfig = async (
42
38
  aws s3 sync ${emailConfigPath} ${deployUrl}
43
39
  --delete
44
40
  --exact-timestamps
41
+ ${flags}
45
42
  `
46
43
  logTitle(
47
44
  `Deploying email configuration for “${configName}” customer configuration to AWS S3 …`,
@@ -49,23 +46,25 @@ export const deployEmailConfig = async (
49
46
  logCommand(cmd)
50
47
 
51
48
  try {
52
- runAwsCommandSync(cmd, {stdout: 'inherit'})
49
+ withAwsAuthenticate(() => runCommandSync(cmd, {stdout: 'inherit'}), options)
53
50
  } catch (error: any) {
54
51
  fail(error.stderr)
55
52
  }
56
53
 
57
54
  /////////////////////////////////////////////////////////////////////////////
58
55
 
59
- logDataTable(
60
- {'Deploy URL:': deployUrl},
56
+ logTitle(
61
57
  `Email configuration for “${configName}” customer configuration is deployed.`,
62
58
  )
59
+ logDataTable({'Deploy URL:': deployUrl})
63
60
 
64
61
  /////////////////////////////////////////////////////////////////////////////
65
62
 
66
- notify({
67
- title: `deploy-email-config`,
68
- message: `Email configuration for “${configName}” customer configuration is deployed.`,
63
+ process.on('exit', () => {
64
+ notify({
65
+ title: `deploy-email-config`,
66
+ message: `Email configuration for “${configName}” customer configuration is deployed.`,
67
+ })
69
68
  })
70
69
  }
71
70
 
@@ -105,3 +104,12 @@ const assertIsNotCore = () => {
105
104
  fail('You cannot deploy widget email configuration for Tamaro Core.')
106
105
  }
107
106
  }
107
+
108
+ ///////////////////////////////////////////////////////////////////////////////
109
+
110
+ const prepareFlags = (
111
+ flags: string[],
112
+ options: DeployEmailConfigOptions,
113
+ ): string[] => {
114
+ return prepareAwsFlags(flags, options)
115
+ }
@@ -1,16 +1,19 @@
1
1
  import {existsSync} from 'fs'
2
- import stripIndent from 'strip-indent'
3
2
  import {
4
- fail,
5
- getIfCoreFns,
6
- getPaths,
7
- getWidgetUuid,
8
- logCommand,
9
- logDataTable,
10
- logTitle,
11
- notify,
12
- } from 'lib/helpers'
13
- import {assertProfileValid, AwsOptions, runAwsCommandSync} from 'lib/aws'
3
+ AWS_CLOUDFRONT_DISTRIBUTION_ID,
4
+ AWS_S3_BUCKET,
5
+ CORE_CONFIG_NAME,
6
+ } from 'lib/constants'
7
+ import {
8
+ assertProfileValid,
9
+ AwsOptions,
10
+ withAwsAuthenticate,
11
+ prepareFlags as prepareAwsFlags,
12
+ } from 'lib/aws'
13
+ import {getIfCoreFns, getPaths, getWidgetUuid} from 'lib/resolve'
14
+ import {logCommand, logDataTable, logTitle} from 'lib/logging'
15
+ import {notify} from 'lib/notifier'
16
+ import {fail, runCommandSync} from 'lib/command'
14
17
 
15
18
  ///////////////////////////////////////////////////////////////////////////////
16
19
 
@@ -20,13 +23,6 @@ export type DeployOptions = AwsOptions & {
20
23
 
21
24
  ///////////////////////////////////////////////////////////////////////////////
22
25
 
23
- export const AWS_S3_BUCKET = 'tamaro.raisenow.com'
24
- export const CORE_CONFIG_NAME = 'tamaro-core'
25
- const AWS_CLOUDFRONT_DISTRIBUTION_ID = 'EHJ1OM458YQ0I'
26
- export const DEFAULT_TAG = 'latest'
27
-
28
- ///////////////////////////////////////////////////////////////////////////////
29
-
30
26
  export const deploy = async (options: DeployOptions): Promise<void> => {
31
27
  const {ifCore} = getIfCoreFns()
32
28
  const paths = getPaths(ifCore)
@@ -34,6 +30,7 @@ export const deploy = async (options: DeployOptions): Promise<void> => {
34
30
  assertOptionsValid(options)
35
31
  assertDistPathExists(paths.appDist)
36
32
 
33
+ const flags = prepareFlags([], options).join(' ')
37
34
  const {tag} = options
38
35
  const configName = ifCore(CORE_CONFIG_NAME, getWidgetUuid())
39
36
  const deployUrl = `s3://${AWS_S3_BUCKET}/${configName}/${tag}`
@@ -45,16 +42,20 @@ export const deploy = async (options: DeployOptions): Promise<void> => {
45
42
 
46
43
  const cmdSyncAll = `
47
44
  aws s3 sync ${paths.appDist} ${deployUrl}
45
+ --quiet
48
46
  --acl public-read
49
- --size-only
50
47
  --exclude ${paths.appDist}/${entryFilename}
51
48
  --cache-control max-age=31536000
49
+ ${flags}
52
50
  `
53
51
  logTitle('Deploying to AWS S3 …')
54
52
  logCommand(cmdSyncAll)
55
53
 
56
54
  try {
57
- runAwsCommandSync(cmdSyncAll, {stdout: 'inherit'})
55
+ withAwsAuthenticate(
56
+ () => runCommandSync(cmdSyncAll, {stdout: 'inherit'}),
57
+ options,
58
+ )
58
59
  } catch (error: any) {
59
60
  fail(error.stderr)
60
61
  }
@@ -65,13 +66,18 @@ export const deploy = async (options: DeployOptions): Promise<void> => {
65
66
 
66
67
  const cmdCpEntry = `
67
68
  aws s3 cp ${paths.appDist}/${entryFilename} ${deployUrl}/${entryFilename}
69
+ --quiet
68
70
  --acl public-read
69
71
  --cache-control max-age=64800
72
+ ${flags}
70
73
  `
71
74
  logCommand(cmdCpEntry)
72
75
 
73
76
  try {
74
- runAwsCommandSync(cmdCpEntry, {stdout: 'inherit'})
77
+ withAwsAuthenticate(
78
+ () => runCommandSync(cmdCpEntry, {stdout: 'inherit'}),
79
+ options,
80
+ )
75
81
  } catch (error: any) {
76
82
  fail(error.stderr)
77
83
  }
@@ -84,13 +90,14 @@ export const deploy = async (options: DeployOptions): Promise<void> => {
84
90
  aws cloudfront create-invalidation
85
91
  --distribution-id ${AWS_CLOUDFRONT_DISTRIBUTION_ID}
86
92
  --paths /${configName}/${tag}/*
93
+ ${flags}
87
94
  `
88
- logTitle('Invalidating edge cache …')
95
+ logTitle('\nInvalidating edge cache …')
89
96
  logCommand(cmdInvalidateCache)
90
97
 
91
98
  try {
92
99
  // ignore output
93
- runAwsCommandSync(cmdInvalidateCache)
100
+ withAwsAuthenticate(() => runCommandSync(cmdInvalidateCache), options)
94
101
  } catch (error: any) {
95
102
  fail(error.stderr)
96
103
  }
@@ -100,23 +107,23 @@ export const deploy = async (options: DeployOptions): Promise<void> => {
100
107
  const demoPage = `https://${AWS_S3_BUCKET}/${configName}/${tag}/index.html`
101
108
  const entryPoint = `https://${AWS_S3_BUCKET}/${configName}/${tag}/${entryFilename}`
102
109
 
103
- logDataTable(
104
- {
105
- 'Demo page:': demoPage,
106
- 'Entry point:': entryPoint,
107
- },
108
- `Bundle for “${configName}” is deployed with tag “${tag}”`,
109
- )
110
+ logTitle(`\nBundle for “${configName}” is deployed with tag “${tag}”.`)
111
+ logDataTable({
112
+ 'Demo page:': demoPage,
113
+ 'Entry point:': entryPoint,
114
+ })
110
115
 
111
116
  /////////////////////////////////////////////////////////////////////////////
112
117
 
113
- notify({
114
- title: 'deploy',
115
- message: stripIndent(`
116
- Bundle for “${configName}” is deployed with tag “${tag}”.
117
- Demo page: ${demoPage}
118
- `),
119
- target: demoPage,
118
+ process.on('exit', () => {
119
+ notify({
120
+ title: 'deploy',
121
+ message: `
122
+ Bundle for “${configName}” is deployed with tag “${tag}”.
123
+ Demo page: ${demoPage}
124
+ Entry point: ${entryPoint}
125
+ `,
126
+ })
120
127
  })
121
128
  }
122
129
 
@@ -143,9 +150,15 @@ const assertDistPathExists = (distPath: string) => {
143
150
  ///////////////////////////////////////////////////////////////////////////////
144
151
 
145
152
  const assertTagValid = (tag: string) => {
146
- const regex = /^[a-zA-Z0-9-_]+$/
153
+ const regex = /^[a-zA-Z0-9-_.]+$/
147
154
 
148
155
  if (!regex.test(tag)) {
149
156
  fail(`Flag "--tag" has forbidden format. Allowed format: ${regex}.`)
150
157
  }
151
158
  }
159
+
160
+ ///////////////////////////////////////////////////////////////////////////////
161
+
162
+ const prepareFlags = (flags: string[], options: DeployOptions): string[] => {
163
+ return prepareAwsFlags(flags, options)
164
+ }