@raisenow/tamaro-cli 1.0.10 → 1.0.11
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/{.eslintrc.js → .eslintrc.cjs} +2 -9
- package/.gitignore +3 -3
- package/.nvmrc +1 -1
- package/{.prettierrc.js → .prettierrc.cjs} +0 -0
- package/{readme.md → README.md} +34 -32
- package/dist/chunk-PIEFLCDU.js +144 -0
- package/dist/cli.js +243 -300
- package/dist/webpack.config.js +114 -252
- package/package.json +23 -31
- package/readme.html +1 -1
- package/src/cli.ts +29 -19
- package/src/commands/build.ts +27 -25
- package/src/commands/deploy-email-config.ts +28 -20
- package/src/commands/deploy.ts +49 -37
- package/src/commands/dev.ts +24 -17
- package/src/commands/list-deployed.ts +22 -12
- package/src/commands/serve.ts +36 -12
- package/src/lib/InterpolateHtmlPlugin.ts +10 -8
- package/src/lib/aws.ts +43 -35
- package/src/lib/command.ts +27 -0
- package/src/lib/constants.ts +7 -0
- package/src/lib/env.ts +102 -0
- package/src/lib/logging.ts +32 -0
- package/src/lib/notifier.ts +22 -0
- package/src/lib/resolve.ts +144 -0
- package/src/webpack.config.ts +23 -31
- package/tsconfig.json +1 -1
- package/src/lib/helpers.ts +0 -356
- package/src/lib/polyfills.js +0 -8
package/src/commands/dev.ts
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
logCommand,
|
|
6
|
-
logTitle,
|
|
7
|
-
resolveOwn,
|
|
8
|
-
runCommandSync,
|
|
9
|
-
} from 'lib/helpers'
|
|
1
|
+
import {getPortPromise} from 'portfinder'
|
|
2
|
+
import {getIfCoreFns, resolveBin, resolveOwn} from 'lib/resolve'
|
|
3
|
+
import {logCommand, logTitle} from 'lib/logging'
|
|
4
|
+
import {fail, runCommandSync} from 'lib/command'
|
|
10
5
|
|
|
11
6
|
///////////////////////////////////////////////////////////////////////////////
|
|
12
7
|
|
|
13
8
|
export type DevOptions = {
|
|
14
9
|
localCore: boolean
|
|
10
|
+
port: string
|
|
15
11
|
}
|
|
16
12
|
|
|
17
13
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -19,13 +15,13 @@ export type DevOptions = {
|
|
|
19
15
|
export const dev = async (options: DevOptions): Promise<void> => {
|
|
20
16
|
assertOptionsValid(options)
|
|
21
17
|
|
|
22
|
-
const flags = prepareFlags(options)
|
|
18
|
+
const flags = (await prepareFlags([], options)).join(' ')
|
|
23
19
|
const {ifCore} = getIfCoreFns()
|
|
24
20
|
const title = ifCore(
|
|
25
21
|
'Running dev web-server for Tamaro Core …',
|
|
26
22
|
'Running dev web-server for customer configuration …',
|
|
27
23
|
)
|
|
28
|
-
const wpBin = resolveBin
|
|
24
|
+
const wpBin = resolveBin('webpack')
|
|
29
25
|
const wpConfig = resolveOwn('dist/webpack.config.js')
|
|
30
26
|
const cmd = `
|
|
31
27
|
${wpBin} serve
|
|
@@ -41,21 +37,32 @@ export const dev = async (options: DevOptions): Promise<void> => {
|
|
|
41
37
|
///////////////////////////////////////////////////////////////////////////////
|
|
42
38
|
|
|
43
39
|
const assertOptionsValid = (options: DevOptions) => {
|
|
44
|
-
const {localCore} = options
|
|
40
|
+
const {localCore, port} = options
|
|
45
41
|
const {ifCore} = getIfCoreFns()
|
|
46
42
|
|
|
47
43
|
if (ifCore() && localCore) {
|
|
48
44
|
fail('Flag "--local-core" is redundant if running in Tamaro Core context.')
|
|
49
45
|
}
|
|
46
|
+
|
|
47
|
+
if (isNaN(Number(port))) {
|
|
48
|
+
fail('Flag "--port" should be a number.')
|
|
49
|
+
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
///////////////////////////////////////////////////////////////////////////////
|
|
53
53
|
|
|
54
|
-
const prepareFlags = (
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
const prepareFlags = async (
|
|
55
|
+
flags: string[],
|
|
56
|
+
options: DevOptions,
|
|
57
|
+
): Promise<string[]> => {
|
|
58
|
+
const {localCore, port: defaultPort} = options
|
|
59
|
+
const port = await getPortPromise({port: Number(defaultPort)})
|
|
60
|
+
|
|
61
|
+
if (localCore) {
|
|
62
|
+
flags.push('--env localCore')
|
|
63
|
+
}
|
|
57
64
|
|
|
58
|
-
flags
|
|
65
|
+
flags.push(`--port ${port}`)
|
|
59
66
|
|
|
60
|
-
return flags
|
|
67
|
+
return flags
|
|
61
68
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import {AWS_S3_BUCKET, CORE_CONFIG_NAME} from 'lib/constants'
|
|
1
2
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from 'lib/
|
|
9
|
-
import {
|
|
10
|
-
import {AWS_S3_BUCKET, CORE_CONFIG_NAME} from 'commands/deploy'
|
|
3
|
+
assertProfileValid,
|
|
4
|
+
AwsOptions,
|
|
5
|
+
withAwsAuthenticate,
|
|
6
|
+
prepareFlags as prepareAwsFlags,
|
|
7
|
+
} from 'lib/aws'
|
|
8
|
+
import {getIfCoreFns, getWidgetUuid} from 'lib/resolve'
|
|
9
|
+
import {logCommand, logTitle} from 'lib/logging'
|
|
10
|
+
import {fail, runCommandSync} from 'lib/command'
|
|
11
11
|
|
|
12
12
|
///////////////////////////////////////////////////////////////////////////////
|
|
13
13
|
|
|
@@ -22,6 +22,7 @@ export const listDeployed = async (
|
|
|
22
22
|
): Promise<void> => {
|
|
23
23
|
assertOptionsValid(options)
|
|
24
24
|
|
|
25
|
+
const flags = prepareFlags([], options).join(' ')
|
|
25
26
|
const {config} = options
|
|
26
27
|
const {ifCore} = getIfCoreFns()
|
|
27
28
|
const configName = config ?? ifCore(CORE_CONFIG_NAME, getWidgetUuid())
|
|
@@ -31,7 +32,7 @@ export const listDeployed = async (
|
|
|
31
32
|
: `Listing deployments of “${configName}” customer configuration …`
|
|
32
33
|
|
|
33
34
|
const deployUrl = `s3://${AWS_S3_BUCKET}/${configName}/`
|
|
34
|
-
const cmd = `aws s3 ls ${deployUrl}`
|
|
35
|
+
const cmd = `aws s3 ls ${deployUrl} ${flags}`
|
|
35
36
|
let out = ''
|
|
36
37
|
|
|
37
38
|
logTitle(title)
|
|
@@ -40,7 +41,7 @@ export const listDeployed = async (
|
|
|
40
41
|
// If customer configuration folder does not exist on AWS S3,
|
|
41
42
|
// command fails with blank stderr, so we need to handle this case.
|
|
42
43
|
try {
|
|
43
|
-
const result =
|
|
44
|
+
const result = withAwsAuthenticate(() => runCommandSync(cmd), options)
|
|
44
45
|
out = result.stdout
|
|
45
46
|
} catch (error: any) {
|
|
46
47
|
out = error.stdout
|
|
@@ -65,7 +66,7 @@ export const listDeployed = async (
|
|
|
65
66
|
.join('\n')
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
console.log(`${text}\n`)
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -93,6 +94,15 @@ const assertConfigValid = (config: string | undefined) => {
|
|
|
93
94
|
|
|
94
95
|
///////////////////////////////////////////////////////////////////////////////
|
|
95
96
|
|
|
97
|
+
const prepareFlags = (
|
|
98
|
+
flags: string[],
|
|
99
|
+
options: ListDeployedOptions,
|
|
100
|
+
): string[] => {
|
|
101
|
+
return prepareAwsFlags(flags, options)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
105
|
+
|
|
96
106
|
const parseTags = (lines: string[]): string[] => {
|
|
97
107
|
const regex = /^\s*PRE\s*/
|
|
98
108
|
|
package/src/commands/serve.ts
CHANGED
|
@@ -1,29 +1,53 @@
|
|
|
1
1
|
import {getPortPromise} from 'portfinder'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
logCommand,
|
|
6
|
-
logTitle,
|
|
7
|
-
runCommandSync,
|
|
8
|
-
} from 'lib/helpers'
|
|
2
|
+
import {getIfCoreFns, getPaths} from 'lib/resolve'
|
|
3
|
+
import {logCommand, logTitle} from 'lib/logging'
|
|
4
|
+
import {fail, runCommandSync} from 'lib/command'
|
|
9
5
|
|
|
10
6
|
///////////////////////////////////////////////////////////////////////////////
|
|
11
7
|
|
|
12
|
-
|
|
8
|
+
export type ServeOptions = {
|
|
9
|
+
port: string
|
|
10
|
+
}
|
|
13
11
|
|
|
14
12
|
///////////////////////////////////////////////////////////////////////////////
|
|
15
13
|
|
|
16
|
-
export const serve = async (): Promise<void> => {
|
|
14
|
+
export const serve = async (options: ServeOptions): Promise<void> => {
|
|
15
|
+
assertOptionsValid(options)
|
|
16
|
+
|
|
17
|
+
const flags = (await prepareFlags([], options)).join(' ')
|
|
17
18
|
const {ifCore} = getIfCoreFns()
|
|
18
19
|
const paths = getPaths(ifCore)
|
|
19
|
-
const port = await getPortPromise({port: DEFAULT_PORT})
|
|
20
20
|
const cmd = `
|
|
21
|
-
npx -y
|
|
21
|
+
npx -y serve ${paths.appDist}
|
|
22
22
|
--cors
|
|
23
|
-
|
|
23
|
+
${flags}
|
|
24
24
|
`
|
|
25
25
|
|
|
26
26
|
logTitle(`Running web-server for pre-built bundle …`)
|
|
27
27
|
logCommand(cmd)
|
|
28
28
|
runCommandSync(cmd, {stdio: 'inherit'})
|
|
29
29
|
}
|
|
30
|
+
|
|
31
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
32
|
+
|
|
33
|
+
const assertOptionsValid = (options: ServeOptions) => {
|
|
34
|
+
const {port} = options
|
|
35
|
+
|
|
36
|
+
if (isNaN(Number(port))) {
|
|
37
|
+
fail('Flag "--port" should be a number.')
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
42
|
+
|
|
43
|
+
const prepareFlags = async (
|
|
44
|
+
flags: string[],
|
|
45
|
+
options: ServeOptions,
|
|
46
|
+
): Promise<string[]> => {
|
|
47
|
+
const {port: defaultPort} = options
|
|
48
|
+
const port = await getPortPromise({port: Number(defaultPort)})
|
|
49
|
+
|
|
50
|
+
flags.push(`-p ${port}`)
|
|
51
|
+
|
|
52
|
+
return flags
|
|
53
|
+
}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import HtmlWebpackPlugin from 'html-webpack-plugin'
|
|
2
1
|
import {Compiler} from 'webpack'
|
|
2
|
+
import HtmlWebpackPlugin from 'html-webpack-plugin'
|
|
3
3
|
import escapeStringRegexp from 'escape-string-regexp'
|
|
4
4
|
|
|
5
5
|
///////////////////////////////////////////////////////////////////////////////
|
|
6
6
|
|
|
7
|
-
type Replacements = {[key: string]: any}
|
|
7
|
+
export type Replacements = {[key: string]: any}
|
|
8
|
+
|
|
9
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
10
|
+
|
|
11
|
+
const PLUGIN_NAME = 'InterpolateHtmlPlugin'
|
|
8
12
|
|
|
9
13
|
///////////////////////////////////////////////////////////////////////////////
|
|
10
14
|
|
|
11
|
-
class InterpolateHtmlPlugin {
|
|
15
|
+
export class InterpolateHtmlPlugin {
|
|
12
16
|
replacements: Replacements
|
|
13
17
|
|
|
14
18
|
constructor(replacements: Replacements) {
|
|
@@ -16,16 +20,16 @@ class InterpolateHtmlPlugin {
|
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
apply(compiler: Compiler): void {
|
|
19
|
-
compiler.hooks.compilation.tap(
|
|
23
|
+
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
20
24
|
const hooks = HtmlWebpackPlugin.getHooks(compilation)
|
|
21
25
|
|
|
22
|
-
hooks.alterAssetTagGroups.tap(
|
|
26
|
+
hooks.alterAssetTagGroups.tap(PLUGIN_NAME, (assets) => {
|
|
23
27
|
this.replacements['ENTRY'] = assets.headTags[0].attributes['src']
|
|
24
28
|
|
|
25
29
|
return assets
|
|
26
30
|
})
|
|
27
31
|
|
|
28
|
-
hooks.afterTemplateExecution.tap(
|
|
32
|
+
hooks.afterTemplateExecution.tap(PLUGIN_NAME, (data) => {
|
|
29
33
|
// Run HTML through a series of user-specified string replacements.
|
|
30
34
|
Object.entries(this.replacements).forEach(([key, value]) => {
|
|
31
35
|
data.html = data.html.replace(
|
|
@@ -39,5 +43,3 @@ class InterpolateHtmlPlugin {
|
|
|
39
43
|
})
|
|
40
44
|
}
|
|
41
45
|
}
|
|
42
|
-
|
|
43
|
-
export default InterpolateHtmlPlugin
|
package/src/lib/aws.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {execaCommandSync} from 'execa'
|
|
2
2
|
import stripIndent from 'strip-indent'
|
|
3
|
-
import {fail
|
|
3
|
+
import {fail} from 'lib/command'
|
|
4
4
|
|
|
5
5
|
///////////////////////////////////////////////////////////////////////////////
|
|
6
6
|
|
|
@@ -10,47 +10,42 @@ export type AwsOptions = {
|
|
|
10
10
|
|
|
11
11
|
///////////////////////////////////////////////////////////////////////////////
|
|
12
12
|
|
|
13
|
-
export const
|
|
13
|
+
export const withAwsAuthenticate = <Result = any>(
|
|
14
|
+
fn: () => Result,
|
|
15
|
+
options: AwsOptions,
|
|
16
|
+
): Result => {
|
|
17
|
+
awsAuthenticate(options)
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export const runAwsCommandSync = (
|
|
18
|
-
command: string,
|
|
19
|
-
options?: SyncOptions,
|
|
20
|
-
): ExecaSyncReturnValue => {
|
|
21
|
-
authenticate()
|
|
22
|
-
|
|
23
|
-
return commandSync(prepareCommand(command), options)
|
|
19
|
+
return fn()
|
|
24
20
|
}
|
|
25
21
|
|
|
26
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
27
23
|
|
|
28
|
-
export const
|
|
29
|
-
// If "AWS_ACCESS_KEY_ID" and "AWS_SECRET_ACCESS_KEY" environment variables are set,
|
|
30
|
-
// then don't try to authenticate the user.
|
|
31
|
-
// This may be useful for using this CLI in automated systems like pipelines.
|
|
24
|
+
export const awsAuthenticate = (options: AwsOptions) => {
|
|
32
25
|
if (isSetEnv()) {
|
|
26
|
+
// Don't try to authenticate the user.
|
|
27
|
+
// This may be useful if CLI is running within an automated system like pipeline,
|
|
28
|
+
// where "AWS_ACCESS_KEY_ID" and "AWS_SECRET_ACCESS_KEY" are used instead of "AWS_PROFILE".
|
|
33
29
|
return
|
|
34
30
|
}
|
|
35
31
|
|
|
36
32
|
try {
|
|
37
|
-
checkIdentity()
|
|
33
|
+
checkIdentity(options)
|
|
38
34
|
} catch (error) {
|
|
39
|
-
login()
|
|
35
|
+
login(options)
|
|
40
36
|
}
|
|
41
37
|
}
|
|
42
38
|
|
|
43
39
|
///////////////////////////////////////////////////////////////////////////////
|
|
44
40
|
|
|
45
|
-
|
|
41
|
+
// Returns true if "AWS_ACCESS_KEY_ID" and "AWS_SECRET_ACCESS_KEY" environment variables are set.
|
|
42
|
+
export const isSetEnv = () => {
|
|
46
43
|
return !!(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY)
|
|
47
44
|
}
|
|
48
45
|
|
|
49
46
|
///////////////////////////////////////////////////////////////////////////////
|
|
50
47
|
|
|
51
48
|
export const assertProfileValid = (profile: string) => {
|
|
52
|
-
// If "AWS_ACCESS_KEY_ID" and "AWS_SECRET_ACCESS_KEY" environment variables are set,
|
|
53
|
-
// then ignore "--profile" flag.
|
|
54
49
|
if (isSetEnv()) {
|
|
55
50
|
return
|
|
56
51
|
}
|
|
@@ -81,18 +76,12 @@ export const assertProfileValid = (profile: string) => {
|
|
|
81
76
|
|
|
82
77
|
fail(message)
|
|
83
78
|
}
|
|
84
|
-
|
|
85
|
-
// Set it here, so we don't need to explicitly pass "--profile" flag
|
|
86
|
-
// to all subsequent "aws" commands.
|
|
87
|
-
// If "AWS_PROFILE" were set before, it will be overriden by "--profile" flag,
|
|
88
|
-
// which has default value, so may be omitted.
|
|
89
|
-
process.env.AWS_PROFILE = profile
|
|
90
79
|
}
|
|
91
80
|
|
|
92
81
|
///////////////////////////////////////////////////////////////////////////////
|
|
93
82
|
|
|
94
83
|
const getAvailableProfiles = (): string[] => {
|
|
95
|
-
const {stdout} =
|
|
84
|
+
const {stdout} = execaCommandSync('aws configure list-profiles')
|
|
96
85
|
|
|
97
86
|
return stdout.split('\n')
|
|
98
87
|
}
|
|
@@ -100,20 +89,39 @@ const getAvailableProfiles = (): string[] => {
|
|
|
100
89
|
///////////////////////////////////////////////////////////////////////////////
|
|
101
90
|
|
|
102
91
|
// Returns caller identity data (output is ignored here).
|
|
103
|
-
// Fails in case of expired
|
|
104
|
-
const checkIdentity = () => {
|
|
105
|
-
|
|
92
|
+
// Fails in case of expired SSO session.
|
|
93
|
+
const checkIdentity = (options: AwsOptions) => {
|
|
94
|
+
const flags = prepareFlags([], options).join(' ')
|
|
95
|
+
|
|
96
|
+
execaCommandSync(`aws sts get-caller-identity ${flags}`)
|
|
106
97
|
}
|
|
107
98
|
|
|
108
99
|
///////////////////////////////////////////////////////////////////////////////
|
|
109
100
|
|
|
110
|
-
// Opens
|
|
101
|
+
// Opens SSO authentication page in the browser.
|
|
111
102
|
// Fails if user canceled authentication process.
|
|
112
|
-
const login = () => {
|
|
103
|
+
const login = (options: AwsOptions) => {
|
|
104
|
+
const flags = prepareFlags([], options).join(' ')
|
|
105
|
+
|
|
113
106
|
try {
|
|
114
|
-
|
|
107
|
+
execaCommandSync(`aws sso login ${flags}`, {stdio: 'inherit'})
|
|
115
108
|
console.log('')
|
|
116
109
|
} catch (error) {
|
|
117
|
-
fail('Login failed')
|
|
110
|
+
fail('Login failed.')
|
|
118
111
|
}
|
|
119
112
|
}
|
|
113
|
+
|
|
114
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
115
|
+
|
|
116
|
+
export const prepareFlags = (
|
|
117
|
+
flags: string[],
|
|
118
|
+
options: AwsOptions,
|
|
119
|
+
): string[] => {
|
|
120
|
+
const {profile} = options
|
|
121
|
+
|
|
122
|
+
if (!isSetEnv()) {
|
|
123
|
+
flags.push(`--profile ${profile}`)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return flags
|
|
127
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {execaCommandSync, ExecaSyncReturnValue, SyncOptions} from 'execa'
|
|
2
|
+
import {logError} from 'lib/logging'
|
|
3
|
+
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
|
|
6
|
+
export const fail = (message?: string) => {
|
|
7
|
+
logError(message)
|
|
8
|
+
process.exit(1)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
12
|
+
|
|
13
|
+
export const prepareCommand = (cmd: string): string => {
|
|
14
|
+
return cmd
|
|
15
|
+
.replace(/\n/gm, ' ')
|
|
16
|
+
.replace(/[ \t]{2,}/gm, ' ')
|
|
17
|
+
.trim()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
21
|
+
|
|
22
|
+
export const runCommandSync = (
|
|
23
|
+
cmd: string,
|
|
24
|
+
options?: SyncOptions,
|
|
25
|
+
): ExecaSyncReturnValue => {
|
|
26
|
+
return execaCommandSync(prepareCommand(cmd), options)
|
|
27
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const DEFAULT_TAG = 'latest'
|
|
2
|
+
export const DEFAULT_PORT = 1234
|
|
3
|
+
export const DEFAULT_AWS_PROFILE = 'payments-prod-cs-deployer'
|
|
4
|
+
export const DEFAULT_AWS_S3_EMAIL_CONFIG_BUCKET = 'rnw-email-service'
|
|
5
|
+
export const AWS_S3_BUCKET = 'tamaro.raisenow.com'
|
|
6
|
+
export const CORE_CONFIG_NAME = 'tamaro-core'
|
|
7
|
+
export const AWS_CLOUDFRONT_DISTRIBUTION_ID = 'EHJ1OM458YQ0I'
|
package/src/lib/env.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import {createRequire} from 'module'
|
|
2
|
+
import type {IfUtilsFn} from 'webpack-config-utils'
|
|
3
|
+
import {expand as dotenvExpand} from 'dotenv-expand'
|
|
4
|
+
import {config as dotenvConfig} from 'dotenv'
|
|
5
|
+
import {getWidgetUuid, resolveApp} from 'lib/resolve'
|
|
6
|
+
|
|
7
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
8
|
+
|
|
9
|
+
export type EnvVars = {
|
|
10
|
+
[key: string]: string | undefined
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
14
|
+
|
|
15
|
+
const require = createRequire(import.meta.url)
|
|
16
|
+
|
|
17
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
18
|
+
|
|
19
|
+
export const getEnvVars = (
|
|
20
|
+
filePath: string,
|
|
21
|
+
ifMin: IfUtilsFn,
|
|
22
|
+
ifCore: IfUtilsFn,
|
|
23
|
+
ifLocalCore: IfUtilsFn,
|
|
24
|
+
) => {
|
|
25
|
+
dotenvExpand(dotenvConfig({path: filePath}))
|
|
26
|
+
|
|
27
|
+
process.env.NODE_ENV ??= ifMin('production', 'development')
|
|
28
|
+
process.env.BABEL_ENV ??= ifMin('production', 'development')
|
|
29
|
+
process.env.EXPOSE_VAR ??= ifCore('rnw.tamaroCore', 'rnw.tamaro')
|
|
30
|
+
process.env.ELEMENT_ATTRIBUTE_DATA_WIDGET ??= ifCore(
|
|
31
|
+
'rnw-tamaro-core',
|
|
32
|
+
'rnw-tamaro',
|
|
33
|
+
)
|
|
34
|
+
process.env.WEBPACK_UNIQUE_NAME ??= ifCore('RnwTamaroCore', 'RnwTamaro')
|
|
35
|
+
|
|
36
|
+
// HMR doesn't work in ie11, it breaks everything.
|
|
37
|
+
// If you want to run dev-server and test in ie11, set HMR_ENABLED to 'false'
|
|
38
|
+
process.env.HMR_ENABLED ??= ifMin('false', 'true')
|
|
39
|
+
|
|
40
|
+
if (ifCore()) {
|
|
41
|
+
process.env.PRODUCT_NAME = 'tamaro'
|
|
42
|
+
|
|
43
|
+
const corePkgPath = resolveApp('package.json')
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
45
|
+
const {version} = require(corePkgPath)
|
|
46
|
+
|
|
47
|
+
process.env.PRODUCT_VERSION = version
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!ifCore()) {
|
|
51
|
+
process.env.WIDGET_UUID = getWidgetUuid()
|
|
52
|
+
|
|
53
|
+
if (ifLocalCore()) {
|
|
54
|
+
process.env.CORE_URL = `http://0.0.0.0:1234/index.js`
|
|
55
|
+
} else {
|
|
56
|
+
let version = process.env.CORE_VERSION
|
|
57
|
+
version = version ? `@${version}` : ''
|
|
58
|
+
|
|
59
|
+
process.env.CORE_URL ??= `https://cdn.jsdelivr.net/npm/@raisenow/tamaro-core${version}/dist/index.js`
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// var names which will be exposed along with "PUBLIC_*" var names
|
|
64
|
+
const varNames = [
|
|
65
|
+
// common
|
|
66
|
+
'NODE_ENV',
|
|
67
|
+
'BABEL_ENV',
|
|
68
|
+
'EXPOSE_VAR',
|
|
69
|
+
'ELEMENT_ATTRIBUTE_DATA_WIDGET',
|
|
70
|
+
'WEBPACK_UNIQUE_NAME',
|
|
71
|
+
|
|
72
|
+
// core
|
|
73
|
+
'PRODUCT_NAME',
|
|
74
|
+
'PRODUCT_VERSION',
|
|
75
|
+
|
|
76
|
+
// config
|
|
77
|
+
'WIDGET_UUID',
|
|
78
|
+
'CORE_URL',
|
|
79
|
+
'CORE_VERSION', // must be explicitly specified in each config
|
|
80
|
+
'IS_CREDIT_CARD_IFRAME',
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
// Collect all vars which names start from "PUBLIC_" or present in "varNames" array
|
|
84
|
+
const raw = Object.keys(process.env)
|
|
85
|
+
.filter((key) => /^PUBLIC_/.test(key) || varNames.includes(key))
|
|
86
|
+
.reduce<EnvVars>((env, key) => {
|
|
87
|
+
env[key] = process.env[key]
|
|
88
|
+
|
|
89
|
+
return env
|
|
90
|
+
}, {})
|
|
91
|
+
|
|
92
|
+
// Stringify all values so we can feed into webpack DefinePlugin
|
|
93
|
+
const stringified = {
|
|
94
|
+
'process.env': Object.keys(raw).reduce<EnvVars>((env, key) => {
|
|
95
|
+
env[key] = JSON.stringify(raw[key])
|
|
96
|
+
|
|
97
|
+
return env
|
|
98
|
+
}, {}),
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return {raw, stringified}
|
|
102
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
import stripIndent from 'strip-indent'
|
|
3
|
+
import columnify from 'columnify'
|
|
4
|
+
|
|
5
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
6
|
+
|
|
7
|
+
export const logTitle = (title: string) => {
|
|
8
|
+
console.log(`${chalk.bold(title)}`)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
12
|
+
|
|
13
|
+
export const logError = (message?: string) => {
|
|
14
|
+
if (message) {
|
|
15
|
+
console.log(chalk.red(message))
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
20
|
+
|
|
21
|
+
export const logCommand = (cmd: string): void => {
|
|
22
|
+
console.log(`\n${chalk.dim(stripIndent(cmd).trim())}\n`)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
26
|
+
|
|
27
|
+
export const logDataTable = (data: {
|
|
28
|
+
[key: string]: string | undefined
|
|
29
|
+
}): void => {
|
|
30
|
+
console.log(columnify(data, {showHeaders: false}))
|
|
31
|
+
console.log('')
|
|
32
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import notifier from 'node-notifier'
|
|
2
|
+
import stripIndent from 'strip-indent'
|
|
3
|
+
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
|
|
6
|
+
export type NotifyArgs = {
|
|
7
|
+
title: string
|
|
8
|
+
message: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
12
|
+
|
|
13
|
+
export const notify = (args: NotifyArgs) => {
|
|
14
|
+
const {title, message = ''} = args
|
|
15
|
+
|
|
16
|
+
notifier.notify({
|
|
17
|
+
title,
|
|
18
|
+
message: stripIndent(message).trim(),
|
|
19
|
+
contentImage: 'https://assets.raisenow.io/favicon.png',
|
|
20
|
+
sound: 'Funk',
|
|
21
|
+
})
|
|
22
|
+
}
|