@raisenow/tamaro-cli 1.0.10 → 1.0.13

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.10",
3
+ "version": "1.0.13",
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,80 +20,71 @@
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
- "@svgr/webpack": "^6.2.1",
35
34
  "@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",
35
+ "@types/lodash": "^4.14.181",
36
+ "@types/node": "^17.0.23",
39
37
  "@types/node-notifier": "^8.0.2",
40
38
  "@types/resolve-bin": "^0.4.1",
41
39
  "@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",
45
- "babel-loader": "^8.2.3",
40
+ "@typescript-eslint/eslint-plugin": "^5.17.0",
41
+ "@typescript-eslint/parser": "^5.17.0",
42
+ "autoprefixer": "^10.4.4",
43
+ "babel-loader": "^8.2.4",
46
44
  "babel-plugin-lodash": "^3.3.4",
47
- "boxen": "^5.1.2",
48
- "chalk": "^4.1.2",
45
+ "chalk": "^5.0.1",
49
46
  "clean-webpack-plugin": "^4.0.0",
50
47
  "columnify": "^1.6.0",
51
- "commander": "^9.0.0",
48
+ "commander": "^9.1.0",
52
49
  "copy-webpack-plugin": "^10.2.4",
53
- "core-js": "^3.21.0",
54
- "css-loader": "^6.6.0",
50
+ "core-js": "^3.21.1",
51
+ "css-loader": "^6.7.1",
55
52
  "css-minimizer-webpack-plugin": "^3.4.1",
56
- "current-script-polyfill": "^1.0.0",
57
53
  "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",
62
- "eslint-config-prettier": "^8.3.0",
54
+ "dotenv-expand": "^8.0.3",
55
+ "escape-string-regexp": "^5.0.0",
56
+ "eslint": "^8.12.0",
57
+ "eslint-config-prettier": "^8.5.0",
63
58
  "eslint-plugin-node": "^11.1.0",
64
- "eslint-plugin-prettier": "^4.0.0",
65
59
  "eslint-plugin-promise": "^6.0.0",
66
- "eslint-webpack-plugin": "^3.1.0",
67
- "execa": "^5.1.1",
60
+ "eslint-webpack-plugin": "^3.1.1",
61
+ "execa": "^6.1.0",
68
62
  "file-loader": "^6.2.0",
69
- "fork-ts-checker-webpack-plugin": "^7.1.1",
63
+ "fork-ts-checker-webpack-plugin": "^7.2.1",
70
64
  "glob": "^7.2.0",
71
65
  "html-loader": "^3.1.0",
72
66
  "html-webpack-plugin": "^5.5.0",
73
67
  "json-loader": "^0.5.7",
74
68
  "lodash": "^4.17.21",
75
- "mini-css-extract-plugin": "^2.5.3",
69
+ "mini-css-extract-plugin": "^2.6.0",
76
70
  "node-notifier": "^10.0.1",
77
- "open": "^8.4.0",
78
71
  "portfinder": "^1.0.28",
79
- "postcss": "^8.4.6",
80
- "postcss-custom-properties": "^12.1.4",
72
+ "postcss": "^8.4.12",
73
+ "postcss-custom-properties": "^12.1.5",
81
74
  "postcss-loader": "^6.2.1",
82
- "prettier": "^2.5.1",
75
+ "prettier": "^2.6.1",
83
76
  "react-refresh": "^0.11.0",
84
- "resolve-bin": "^1.0.0",
85
77
  "resolve-url-loader": "^5.0.0",
86
- "sass": "^1.49.7",
87
- "sass-loader": "^12.4.0",
78
+ "sass": "^1.49.10",
79
+ "sass-loader": "^12.6.0",
88
80
  "source-map-loader": "^3.0.1",
89
- "strip-indent": "^3.0.0",
81
+ "strip-indent": "^4.0.0",
90
82
  "style-loader": "^3.3.1",
91
83
  "tsconfig-paths-webpack-plugin": "^3.5.2",
92
- "tsup": "^5.11.13",
93
- "typescript": "^4.5.5",
94
- "unfetch": "^4.2.0",
84
+ "tsup": "^5.12.1",
85
+ "typescript": "^4.6.3",
95
86
  "url-loader": "^4.1.1",
96
- "webpack": "^5.68.0",
87
+ "webpack": "^5.70.0",
97
88
  "webpack-cli": "^4.9.2",
98
89
  "webpack-config-utils": "^2.3.1",
99
90
  "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,11 @@ 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}`)
53
+ .option('--env <env>', 'Environment (dev, stage, prod)')
48
54
  .action(async (options: DevOptions) => {
49
55
  await dev(options)
50
56
  })
@@ -56,16 +62,18 @@ cli
56
62
  )
57
63
  .option(
58
64
  '--local-core',
59
- 'Load Tamaro Core from localhost instead of the CDN',
65
+ 'Load Tamaro Core from localhost:1234 instead of the CDN',
60
66
  false,
61
67
  )
62
68
  .option('--analyze', 'Generate bundle statistics to "reports" folder', false)
69
+ .option('--serve', 'Run the generated bundle with a local web server', false)
70
+ .option('--port <port>', 'Web server port', `${DEFAULT_PORT}`)
71
+ .option('--env <env>', 'Environment (dev, stage, prod)')
63
72
  .option(
64
73
  '--deploy',
65
74
  'Deploy Tamaro Core or a customer configuration bundle to AWS S3',
66
75
  false,
67
76
  )
68
- .option('--serve', 'Run the generated bundle with a local web server', false)
69
77
  .option(
70
78
  '--tag <tag>',
71
79
  'Tag which should be used for the deployment of the bundle',
@@ -76,16 +84,24 @@ cli
76
84
  'AWS profile which should be used for the deployment of the bundle',
77
85
  DEFAULT_AWS_PROFILE,
78
86
  )
79
- .action(async (options: BuildOptions & DeployOptions) => {
87
+ .action(async (options: BuildOptions & ServeOptions & DeployOptions) => {
80
88
  await build(options)
81
89
 
90
+ if (options.serve) {
91
+ await serve(options)
92
+ }
93
+
82
94
  if (options.deploy) {
83
95
  await deploy(options)
84
96
  }
97
+ })
85
98
 
86
- if (options.serve) {
87
- await serve()
88
- }
99
+ cli
100
+ .command('serve')
101
+ .description('Run a local web server for pre-built bundle')
102
+ .option('--port <port>', 'Web server port', `${DEFAULT_PORT}`)
103
+ .action(async (options: ServeOptions) => {
104
+ await serve(options)
89
105
  })
90
106
 
91
107
  cli
@@ -107,13 +123,6 @@ cli
107
123
  await deploy(options)
108
124
  })
109
125
 
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
126
  cli
118
127
  .command('list-deployed')
119
128
  .description(
@@ -156,6 +165,9 @@ cli
156
165
  } catch (error: any) {
157
166
  if (error.signal === 'SIGINT' && error.signalDescription) {
158
167
  logError(`\n${error.signalDescription}`)
168
+ } else {
169
+ console.log('')
170
+ logError(error.stack)
159
171
  }
160
172
  }
161
173
  })()
@@ -1,26 +1,26 @@
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 {assertEnvValid} from 'lib/env'
11
+ import {logCommand, logTitle} from 'lib/logging'
12
+ import {notify} from 'lib/notifier'
13
+ import {fail, runCommandSync} from 'lib/command'
14
+ import {DeployOptions} from 'commands/deploy'
16
15
 
17
16
  ///////////////////////////////////////////////////////////////////////////////
18
17
 
19
18
  export type BuildOptions = {
20
19
  localCore: boolean
21
20
  analyze: boolean
22
- deploy: boolean
23
21
  serve: boolean
22
+ deploy: boolean
23
+ env: string
24
24
  }
25
25
 
26
26
  ///////////////////////////////////////////////////////////////////////////////
@@ -30,7 +30,7 @@ export const build = async (
30
30
  ): Promise<void> => {
31
31
  assertOptionsValid(options)
32
32
 
33
- const flags = prepareFlags(options)
33
+ const flags = prepareFlags([], options).join(' ')
34
34
  const {ifCore} = getIfCoreFns()
35
35
  const paths = getPaths(ifCore)
36
36
  const configName = ifCore(CORE_CONFIG_NAME, getWidgetUuid())
@@ -39,7 +39,7 @@ export const build = async (
39
39
  `Building optimised (minified) bundle of “${configName}” customer configuration …`,
40
40
  )
41
41
 
42
- const wpBin = resolveBin.sync('webpack')
42
+ const wpBin = resolveBin('webpack')
43
43
  const wpConfig = resolveOwn('dist/webpack.config.js')
44
44
  const cmd = `
45
45
  ${wpBin}
@@ -54,44 +54,49 @@ export const build = async (
54
54
 
55
55
  /////////////////////////////////////////////////////////////////////////////
56
56
 
57
- logDataTable(
58
- {'Path:': paths.appDist},
59
- `Bundle for “${configName}” customer configuration is done.`,
60
- )
57
+ logTitle(`\nBundle for “${configName}” customer configuration is done.`)
58
+ console.log(`Path: ${paths.appDist}\n`)
61
59
 
62
60
  /////////////////////////////////////////////////////////////////////////////
63
61
 
64
- notify({
65
- title: 'build',
66
- message: `Bundle for “${configName}” customer configuration is done.`,
62
+ process.on('exit', () => {
63
+ notify({
64
+ title: 'build',
65
+ message: `Bundle for “${configName}” customer configuration is done.`,
66
+ })
67
67
  })
68
68
  }
69
69
 
70
70
  ///////////////////////////////////////////////////////////////////////////////
71
71
 
72
72
  const assertOptionsValid = (options: BuildOptions & DeployOptions) => {
73
- const {localCore, deploy, profile} = options
73
+ const {localCore, deploy, profile, env} = options
74
74
  const {ifCore} = getIfCoreFns()
75
75
 
76
76
  if (ifCore() && localCore) {
77
- fail('Flag "--local-core" is redundant if running in Tamaro Core context.')
77
+ fail('Flag “--local-core is redundant if running in Tamaro Core context.')
78
78
  }
79
79
 
80
80
  if (localCore && deploy) {
81
- fail('Flags "--local-core" and "--deploy" must not be used together.')
81
+ fail('Flags “--local-core and “--deploy must not be used together.')
82
82
  }
83
83
 
84
84
  assertProfileValid(profile)
85
+ assertEnvValid(env)
85
86
  }
86
87
 
87
88
  ///////////////////////////////////////////////////////////////////////////////
88
89
 
89
- const prepareFlags = (options: BuildOptions): string => {
90
+ const prepareFlags = (flags: string[], options: BuildOptions): string[] => {
90
91
  const {localCore, analyze} = options
91
- let flags: string[] = []
92
92
 
93
- flags = localCore ? [...flags, '--env localCore'] : flags
94
- flags = analyze ? [...flags, '--env analyze'] : flags
93
+ if (localCore) {
94
+ flags.push('--env localCore')
95
+ }
96
+
97
+ if (analyze) {
98
+ flags.push('--env analyze')
99
+ }
95
100
 
96
- return flags.join(' ')
101
+ return flags
97
102
  }
@@ -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
 
@@ -92,7 +91,7 @@ const assertBucketValid = (tag: string) => {
92
91
  const regex = /^[a-zA-Z0-9-_]+$/
93
92
 
94
93
  if (!regex.test(tag)) {
95
- fail(`Flag "--bucket" has forbidden format. Allowed format: ${regex}.`)
94
+ fail(`Flag “--bucket has forbidden format. Allowed format: ${regex}.`)
96
95
  }
97
96
  }
98
97
 
@@ -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
- fail(`Flag "--tag" has forbidden format. Allowed format: ${regex}.`)
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
+ }