@raisenow/tamaro-cli 1.0.12 → 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/README.md CHANGED
@@ -39,6 +39,7 @@ Runs the local development server for _Tamaro Core_ or a particular customer con
39
39
 
40
40
  - `--local-core` – Load _Tamaro Core_ from localhost:1234 instead of the CDN
41
41
  - `--port <port>` – Web server port (default: 1234)
42
+ - `--env <env>` – Environment (dev, stage, prod)
42
43
 
43
44
  ### Run local server using Tamaro Core from CDN
44
45
 
@@ -75,6 +76,7 @@ Build an optimised (minified) bundle of _Tamaro Core_ or a customer configuratio
75
76
  - `--analyze` – Generate bundle statistics to `reports` folder
76
77
  - `--serve` – Run the generated bundle with a local web server
77
78
  - `--port <port>` – Web server port (default: 1234)
79
+ - `--env <env>` – Environment (dev, stage, prod)
78
80
  - `--deploy` – Deploy _Tamaro Core_ or a customer configuration bundle to AWS S3
79
81
  - `--tag <tag>` – Tag which should be used for the deployment of the bundle (default: “latest”)
80
82
  - `--profile <profile>` – AWS profile which should be used for the deployment of the bundle (default: “payments-prod-cs-deployer”)
@@ -81,7 +81,7 @@ var getPaths = (ifCore) => {
81
81
  appNodeModules: resolveApp("node_modules"),
82
82
  appTsConfig: resolveApp("tsconfig.json"),
83
83
  appHtml: resolveApp("src/*.html"),
84
- appEnv: resolveApp(".env"),
84
+ appEnv: resolveApp(".env*"),
85
85
  appTailwindConfig: resolveApp("tailwind.config.js")
86
86
  }, {
87
87
  app: resolveApp("."),
@@ -90,7 +90,7 @@ var getPaths = (ifCore) => {
90
90
  appNodeModules: resolveApp("../../node_modules"),
91
91
  appTsConfig: resolveApp("tsconfig.json"),
92
92
  appHtml: resolveApp("*.html"),
93
- appEnv: resolveApp(".env"),
93
+ appEnv: resolveApp(".env*"),
94
94
  appTailwindConfig: void 0
95
95
  });
96
96
  };
@@ -126,6 +126,107 @@ var getIfCoreFns = () => {
126
126
  process.exit(1);
127
127
  };
128
128
 
129
+ // src/lib/env.ts
130
+ import { createRequire as createRequire2 } from "module";
131
+ import { basename as basename2 } from "path";
132
+ import glob from "glob";
133
+ import { expand as dotenvExpand } from "dotenv-expand";
134
+ import { config as dotenvConfig } from "dotenv";
135
+ import stripIndent3 from "strip-indent";
136
+
137
+ // src/lib/command.ts
138
+ import { execaCommandSync } from "execa";
139
+ var fail = (message) => {
140
+ logError(message);
141
+ process.exit(1);
142
+ };
143
+ var prepareCommand = (cmd) => {
144
+ return cmd.replace(/\n/gm, " ").replace(/[ \t]{2,}/gm, " ").trim();
145
+ };
146
+ var runCommandSync = (cmd, options) => {
147
+ return execaCommandSync(prepareCommand(cmd), options);
148
+ };
149
+
150
+ // src/lib/env.ts
151
+ var require3 = createRequire2(import.meta.url);
152
+ var getEnvVars = (files, ifMin, ifCore, ifLocalCore) => {
153
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
154
+ const filePath = files.find((file) => basename2(file) === ".env");
155
+ dotenvExpand(dotenvConfig({ path: filePath }));
156
+ (_b = (_a = process.env).NODE_ENV) != null ? _b : _a.NODE_ENV = ifMin("production", "development");
157
+ (_d = (_c = process.env).BABEL_ENV) != null ? _d : _c.BABEL_ENV = ifMin("production", "development");
158
+ (_f = (_e = process.env).EXPOSE_VAR) != null ? _f : _e.EXPOSE_VAR = ifCore("rnw.tamaroCore", "rnw.tamaro");
159
+ (_h = (_g = process.env).ELEMENT_ATTRIBUTE_DATA_WIDGET) != null ? _h : _g.ELEMENT_ATTRIBUTE_DATA_WIDGET = ifCore("rnw-tamaro-core", "rnw-tamaro");
160
+ (_j = (_i = process.env).WEBPACK_UNIQUE_NAME) != null ? _j : _i.WEBPACK_UNIQUE_NAME = ifCore("RnwTamaroCore", "RnwTamaro");
161
+ process.env.BUILD_DATE = new Date().toISOString();
162
+ (_l = (_k = process.env).HMR_ENABLED) != null ? _l : _k.HMR_ENABLED = ifMin("false", "true");
163
+ if (ifCore()) {
164
+ process.env.PRODUCT_NAME = "tamaro";
165
+ const corePkgPath = resolveApp("package.json");
166
+ const { version } = require3(corePkgPath);
167
+ process.env.PRODUCT_VERSION = version;
168
+ }
169
+ if (!ifCore()) {
170
+ process.env.WIDGET_UUID = getWidgetUuid();
171
+ if (ifLocalCore()) {
172
+ process.env.CORE_URL = `http://0.0.0.0:1234/index.js`;
173
+ } else {
174
+ let version = process.env.CORE_VERSION;
175
+ version = version ? `@${version}` : "";
176
+ (_n = (_m = process.env).CORE_URL) != null ? _n : _m.CORE_URL = `https://cdn.jsdelivr.net/npm/@raisenow/tamaro-core${version}/dist/index.js`;
177
+ }
178
+ }
179
+ const varNames = [
180
+ "NODE_ENV",
181
+ "BABEL_ENV",
182
+ "EXPOSE_VAR",
183
+ "ELEMENT_ATTRIBUTE_DATA_WIDGET",
184
+ "WEBPACK_UNIQUE_NAME",
185
+ "BUILD_DATE",
186
+ "PRODUCT_NAME",
187
+ "PRODUCT_VERSION",
188
+ "WIDGET_UUID",
189
+ "CORE_URL",
190
+ "CORE_VERSION",
191
+ "IS_CREDIT_CARD_IFRAME"
192
+ ];
193
+ const raw = Object.keys(process.env).filter((key) => /^PUBLIC_/.test(key) || varNames.includes(key)).reduce((env, key) => {
194
+ env[key] = process.env[key];
195
+ return env;
196
+ }, {});
197
+ const stringified = {
198
+ "process.env": Object.keys(raw).reduce((env, key) => {
199
+ env[key] = JSON.stringify(raw[key]);
200
+ return env;
201
+ }, {})
202
+ };
203
+ return { raw, stringified };
204
+ };
205
+ var assertEnvValid = (env) => {
206
+ const { ifCore } = getIfCoreFns();
207
+ const paths = getPaths(ifCore);
208
+ const files = glob.sync(paths.appEnv);
209
+ const envs = files.map((file) => basename2(file).replace(/^\.env\.?/, "")).filter((v) => !!v);
210
+ if (envs.length === 0) {
211
+ if (env) {
212
+ console.log("Flag \u201C--env\u201D is ignored.");
213
+ }
214
+ }
215
+ if (envs.length !== 0) {
216
+ if (!env) {
217
+ fail("Flag \u201C--env\u201D is required.");
218
+ }
219
+ if (!envs.includes(env)) {
220
+ fail(stripIndent3(`
221
+ Flag \u201C--env\u201D has wrong value.
222
+ Available values are: ${envs.map((v) => `\u201C${v}\u201D`).join(", ")}.
223
+ `));
224
+ }
225
+ const filePath = files.find((file) => basename2(file) === `.env.${env}`);
226
+ dotenvExpand(dotenvConfig({ path: filePath }));
227
+ }
228
+ };
229
+
129
230
  export {
130
231
  __spreadValues,
131
232
  logTitle,
@@ -140,5 +241,9 @@ export {
140
241
  getWidgetUuid,
141
242
  getPaths,
142
243
  getRelativePaths,
143
- getIfCoreFns
244
+ getIfCoreFns,
245
+ fail,
246
+ runCommandSync,
247
+ getEnvVars,
248
+ assertEnvValid
144
249
  };
package/dist/cli.js CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ assertEnvValid,
4
+ fail,
3
5
  getIfCoreFns,
4
6
  getPaths,
5
7
  getWidgetUuid,
@@ -8,15 +10,16 @@ import {
8
10
  logError,
9
11
  logTitle,
10
12
  resolveBin,
11
- resolveOwn
12
- } from "./chunk-PIEFLCDU.js";
13
+ resolveOwn,
14
+ runCommandSync
15
+ } from "./chunk-OXDXJ5B5.js";
13
16
 
14
17
  // src/cli.ts
15
18
  import { createCommand } from "commander";
16
19
 
17
20
  // package.json
18
21
  var name = "@raisenow/tamaro-cli";
19
- var version = "1.0.12";
22
+ var version = "1.0.13";
20
23
  var author = {
21
24
  name: "RaiseNow",
22
25
  email: "development@raisenow.com"
@@ -47,17 +50,16 @@ var dependencies = {
47
50
  "@babel/runtime-corejs3": "^7.17.8",
48
51
  "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4",
49
52
  "@statoscope/webpack-plugin": "^5.20.1",
50
- "@svgr/webpack": "^6.2.1",
51
53
  "@types/columnify": "^1.5.1",
52
- "@types/lodash": "^4.14.180",
53
- "@types/node": "^17.0.21",
54
+ "@types/lodash": "^4.14.181",
55
+ "@types/node": "^17.0.23",
54
56
  "@types/node-notifier": "^8.0.2",
55
57
  "@types/resolve-bin": "^0.4.1",
56
58
  "@types/webpack-config-utils": "^2.3.1",
57
- "@typescript-eslint/eslint-plugin": "^5.15.0",
58
- "@typescript-eslint/parser": "^5.15.0",
59
+ "@typescript-eslint/eslint-plugin": "^5.17.0",
60
+ "@typescript-eslint/parser": "^5.17.0",
59
61
  autoprefixer: "^10.4.4",
60
- "babel-loader": "^8.2.3",
62
+ "babel-loader": "^8.2.4",
61
63
  "babel-plugin-lodash": "^3.3.4",
62
64
  chalk: "^5.0.1",
63
65
  "clean-webpack-plugin": "^4.0.0",
@@ -70,7 +72,7 @@ var dependencies = {
70
72
  dotenv: "^16.0.0",
71
73
  "dotenv-expand": "^8.0.3",
72
74
  "escape-string-regexp": "^5.0.0",
73
- eslint: "^8.11.0",
75
+ eslint: "^8.12.0",
74
76
  "eslint-config-prettier": "^8.5.0",
75
77
  "eslint-plugin-node": "^11.1.0",
76
78
  "eslint-plugin-promise": "^6.0.0",
@@ -89,17 +91,17 @@ var dependencies = {
89
91
  postcss: "^8.4.12",
90
92
  "postcss-custom-properties": "^12.1.5",
91
93
  "postcss-loader": "^6.2.1",
92
- prettier: "^2.6.0",
94
+ prettier: "^2.6.1",
93
95
  "react-refresh": "^0.11.0",
94
96
  "resolve-url-loader": "^5.0.0",
95
- sass: "^1.49.9",
97
+ sass: "^1.49.10",
96
98
  "sass-loader": "^12.6.0",
97
99
  "source-map-loader": "^3.0.1",
98
100
  "strip-indent": "^4.0.0",
99
101
  "style-loader": "^3.3.1",
100
102
  "tsconfig-paths-webpack-plugin": "^3.5.2",
101
103
  tsup: "^5.12.1",
102
- typescript: "^4.6.2",
104
+ typescript: "^4.6.3",
103
105
  "url-loader": "^4.1.1",
104
106
  webpack: "^5.70.0",
105
107
  "webpack-cli": "^4.9.2",
@@ -129,21 +131,6 @@ var AWS_CLOUDFRONT_DISTRIBUTION_ID = "EHJ1OM458YQ0I";
129
131
 
130
132
  // src/commands/dev.ts
131
133
  import { getPortPromise } from "portfinder";
132
-
133
- // src/lib/command.ts
134
- import { execaCommandSync } from "execa";
135
- var fail = (message) => {
136
- logError(message);
137
- process.exit(1);
138
- };
139
- var prepareCommand = (cmd) => {
140
- return cmd.replace(/\n/gm, " ").replace(/[ \t]{2,}/gm, " ").trim();
141
- };
142
- var runCommandSync = (cmd, options) => {
143
- return execaCommandSync(prepareCommand(cmd), options);
144
- };
145
-
146
- // src/commands/dev.ts
147
134
  var dev = async (options) => {
148
135
  assertOptionsValid(options);
149
136
  const flags = (await prepareFlags([], options)).join(" ");
@@ -161,14 +148,15 @@ var dev = async (options) => {
161
148
  runCommandSync(cmd, { stdio: "inherit" });
162
149
  };
163
150
  var assertOptionsValid = (options) => {
164
- const { localCore, port } = options;
151
+ const { localCore, port, env } = options;
165
152
  const { ifCore } = getIfCoreFns();
166
153
  if (ifCore() && localCore) {
167
- fail('Flag "--local-core" is redundant if running in Tamaro Core context.');
154
+ fail("Flag \u201C--local-core\u201D is redundant if running in Tamaro Core context.");
168
155
  }
169
156
  if (isNaN(Number(port))) {
170
- fail('Flag "--port" should be a number.');
157
+ fail("Flag \u201C--port\u201D should be a number.");
171
158
  }
159
+ assertEnvValid(env);
172
160
  };
173
161
  var prepareFlags = async (flags, options) => {
174
162
  const { localCore, port: defaultPort } = options;
@@ -181,7 +169,7 @@ var prepareFlags = async (flags, options) => {
181
169
  };
182
170
 
183
171
  // src/lib/aws.ts
184
- import { execaCommandSync as execaCommandSync2 } from "execa";
172
+ import { execaCommandSync } from "execa";
185
173
  import stripIndent from "strip-indent";
186
174
  var withAwsAuthenticate = (fn, options) => {
187
175
  awsAuthenticate(options);
@@ -227,17 +215,17 @@ var assertProfileValid = (profile) => {
227
215
  }
228
216
  };
229
217
  var getAvailableProfiles = () => {
230
- const { stdout } = execaCommandSync2("aws configure list-profiles");
218
+ const { stdout } = execaCommandSync("aws configure list-profiles");
231
219
  return stdout.split("\n");
232
220
  };
233
221
  var checkIdentity = (options) => {
234
222
  const flags = prepareFlags2([], options).join(" ");
235
- execaCommandSync2(`aws sts get-caller-identity ${flags}`);
223
+ execaCommandSync(`aws sts get-caller-identity ${flags}`);
236
224
  };
237
225
  var login = (options) => {
238
226
  const flags = prepareFlags2([], options).join(" ");
239
227
  try {
240
- execaCommandSync2(`aws sso login ${flags}`, { stdio: "inherit" });
228
+ execaCommandSync(`aws sso login ${flags}`, { stdio: "inherit" });
241
229
  console.log("");
242
230
  } catch (error) {
243
231
  fail("Login failed.");
@@ -295,15 +283,16 @@ Bundle for \u201C${configName}\u201D customer configuration is done.`);
295
283
  });
296
284
  };
297
285
  var assertOptionsValid2 = (options) => {
298
- const { localCore, deploy: deploy2, profile } = options;
286
+ const { localCore, deploy: deploy2, profile, env } = options;
299
287
  const { ifCore } = getIfCoreFns();
300
288
  if (ifCore() && localCore) {
301
- fail('Flag "--local-core" is redundant if running in Tamaro Core context.');
289
+ fail("Flag \u201C--local-core\u201D is redundant if running in Tamaro Core context.");
302
290
  }
303
291
  if (localCore && deploy2) {
304
- fail('Flags "--local-core" and "--deploy" must not be used together.');
292
+ fail("Flags \u201C--local-core\u201D and \u201C--deploy\u201D must not be used together.");
305
293
  }
306
294
  assertProfileValid(profile);
295
+ assertEnvValid(env);
307
296
  };
308
297
  var prepareFlags3 = (flags, options) => {
309
298
  const { localCore, analyze } = options;
@@ -404,7 +393,7 @@ var assertDistPathExists = (distPath) => {
404
393
  var assertTagValid = (tag) => {
405
394
  const regex = /^[a-zA-Z0-9-_.]+$/;
406
395
  if (!regex.test(tag)) {
407
- fail(`Flag "--tag" has forbidden format. Allowed format: ${regex}.`);
396
+ fail(`Flag \u201C--tag\u201D has forbidden format. Allowed format: ${regex}.`);
408
397
  }
409
398
  };
410
399
  var prepareFlags4 = (flags, options) => {
@@ -486,7 +475,7 @@ var assertConfigValid = (config) => {
486
475
  }
487
476
  const regex = /^[a-zA-Z0-9-_]+$/;
488
477
  if (!regex.test(config)) {
489
- fail(`Flag "--config" has forbidden format. Allowed format: ${regex}.`);
478
+ fail(`Flag \u201C--config\u201D has forbidden format. Allowed format: ${regex}.`);
490
479
  }
491
480
  };
492
481
  var prepareFlags6 = (flags, options) => {
@@ -545,7 +534,7 @@ var assertEmailConfigPathExists = (distPath) => {
545
534
  var assertBucketValid = (tag) => {
546
535
  const regex = /^[a-zA-Z0-9-_]+$/;
547
536
  if (!regex.test(tag)) {
548
- fail(`Flag "--bucket" has forbidden format. Allowed format: ${regex}.`);
537
+ fail(`Flag \u201C--bucket\u201D has forbidden format. Allowed format: ${regex}.`);
549
538
  }
550
539
  };
551
540
  var assertIsNotCore = () => {
@@ -566,10 +555,10 @@ process.on("SIGINT", () => {
566
555
  process.exit(1);
567
556
  });
568
557
  var cli = createCommand().name(package_default.name).version(package_default.version, "-v, --version");
569
- cli.command("dev").description("Run the local development server for Tamaro Core or a particular customer configuration").option("--local-core", "Load Tamaro Core from localhost:1234 instead of the CDN", false).option("--port <port>", "Web server port", `${DEFAULT_PORT}`).action(async (options) => {
558
+ cli.command("dev").description("Run the local development server for Tamaro Core or a particular customer configuration").option("--local-core", "Load Tamaro Core from localhost:1234 instead of the CDN", false).option("--port <port>", "Web server port", `${DEFAULT_PORT}`).option("--env <env>", "Environment (dev, stage, prod)").action(async (options) => {
570
559
  await dev(options);
571
560
  });
572
- cli.command("build").description("Build an optimised (minified) bundle of Tamaro Core or a customer configuration").option("--local-core", "Load Tamaro Core from localhost:1234 instead of the CDN", false).option("--analyze", 'Generate bundle statistics to "reports" folder', false).option("--serve", "Run the generated bundle with a local web server", false).option("--port <port>", "Web server port", `${DEFAULT_PORT}`).option("--deploy", "Deploy Tamaro Core or a customer configuration bundle to AWS S3", false).option("--tag <tag>", "Tag which should be used for the deployment of the bundle", DEFAULT_TAG).option("--profile <profile>", "AWS profile which should be used for the deployment of the bundle", DEFAULT_AWS_PROFILE).action(async (options) => {
561
+ cli.command("build").description("Build an optimised (minified) bundle of Tamaro Core or a customer configuration").option("--local-core", "Load Tamaro Core from localhost:1234 instead of the CDN", false).option("--analyze", 'Generate bundle statistics to "reports" folder', false).option("--serve", "Run the generated bundle with a local web server", false).option("--port <port>", "Web server port", `${DEFAULT_PORT}`).option("--env <env>", "Environment (dev, stage, prod)").option("--deploy", "Deploy Tamaro Core or a customer configuration bundle to AWS S3", false).option("--tag <tag>", "Tag which should be used for the deployment of the bundle", DEFAULT_TAG).option("--profile <profile>", "AWS profile which should be used for the deployment of the bundle", DEFAULT_AWS_PROFILE).action(async (options) => {
573
562
  await build(options);
574
563
  if (options.serve) {
575
564
  await serve(options);
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  __spreadValues,
3
3
  extensions,
4
+ getEnvVars,
4
5
  getIfCoreFns,
5
6
  getPaths,
6
7
  getRelativePaths,
7
- getWidgetUuid,
8
8
  logDataTable,
9
9
  logTitle,
10
10
  moduleFileExtensions,
11
11
  resolveApp
12
- } from "./chunk-PIEFLCDU.js";
12
+ } from "./chunk-OXDXJ5B5.js";
13
13
 
14
14
  // src/webpack.config.ts
15
- import { createRequire as createRequire2 } from "module";
15
+ import { createRequire } from "module";
16
16
  import { basename, dirname } from "path";
17
17
  import { existsSync } from "fs";
18
18
  import glob from "glob";
@@ -55,64 +55,8 @@ var InterpolateHtmlPlugin = class {
55
55
  }
56
56
  };
57
57
 
58
- // src/lib/env.ts
59
- import { createRequire } from "module";
60
- import { expand as dotenvExpand } from "dotenv-expand";
61
- import { config as dotenvConfig } from "dotenv";
62
- var require2 = createRequire(import.meta.url);
63
- var getEnvVars = (filePath, ifMin, ifCore, ifLocalCore) => {
64
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
65
- dotenvExpand(dotenvConfig({ path: filePath }));
66
- (_b = (_a = process.env).NODE_ENV) != null ? _b : _a.NODE_ENV = ifMin("production", "development");
67
- (_d = (_c = process.env).BABEL_ENV) != null ? _d : _c.BABEL_ENV = ifMin("production", "development");
68
- (_f = (_e = process.env).EXPOSE_VAR) != null ? _f : _e.EXPOSE_VAR = ifCore("rnw.tamaroCore", "rnw.tamaro");
69
- (_h = (_g = process.env).ELEMENT_ATTRIBUTE_DATA_WIDGET) != null ? _h : _g.ELEMENT_ATTRIBUTE_DATA_WIDGET = ifCore("rnw-tamaro-core", "rnw-tamaro");
70
- (_j = (_i = process.env).WEBPACK_UNIQUE_NAME) != null ? _j : _i.WEBPACK_UNIQUE_NAME = ifCore("RnwTamaroCore", "RnwTamaro");
71
- (_l = (_k = process.env).HMR_ENABLED) != null ? _l : _k.HMR_ENABLED = ifMin("false", "true");
72
- if (ifCore()) {
73
- process.env.PRODUCT_NAME = "tamaro";
74
- const corePkgPath = resolveApp("package.json");
75
- const { version } = require2(corePkgPath);
76
- process.env.PRODUCT_VERSION = version;
77
- }
78
- if (!ifCore()) {
79
- process.env.WIDGET_UUID = getWidgetUuid();
80
- if (ifLocalCore()) {
81
- process.env.CORE_URL = `http://0.0.0.0:1234/index.js`;
82
- } else {
83
- let version = process.env.CORE_VERSION;
84
- version = version ? `@${version}` : "";
85
- (_n = (_m = process.env).CORE_URL) != null ? _n : _m.CORE_URL = `https://cdn.jsdelivr.net/npm/@raisenow/tamaro-core${version}/dist/index.js`;
86
- }
87
- }
88
- const varNames = [
89
- "NODE_ENV",
90
- "BABEL_ENV",
91
- "EXPOSE_VAR",
92
- "ELEMENT_ATTRIBUTE_DATA_WIDGET",
93
- "WEBPACK_UNIQUE_NAME",
94
- "PRODUCT_NAME",
95
- "PRODUCT_VERSION",
96
- "WIDGET_UUID",
97
- "CORE_URL",
98
- "CORE_VERSION",
99
- "IS_CREDIT_CARD_IFRAME"
100
- ];
101
- const raw = Object.keys(process.env).filter((key) => /^PUBLIC_/.test(key) || varNames.includes(key)).reduce((env, key) => {
102
- env[key] = process.env[key];
103
- return env;
104
- }, {});
105
- const stringified = {
106
- "process.env": Object.keys(raw).reduce((env, key) => {
107
- env[key] = JSON.stringify(raw[key]);
108
- return env;
109
- }, {})
110
- };
111
- return { raw, stringified };
112
- };
113
-
114
58
  // src/webpack.config.ts
115
- var require3 = createRequire2(import.meta.url);
59
+ var require2 = createRequire(import.meta.url);
116
60
  var imageInlineSizeLimit = 0;
117
61
  var getWebpackConfig = async (env) => {
118
62
  const { ifMin, ifNotMin } = getIfUtils(env, ["min"]);
@@ -121,7 +65,8 @@ var getWebpackConfig = async (env) => {
121
65
  const { ifCore } = getIfCoreFns();
122
66
  const paths = getPaths(ifCore);
123
67
  const appHtmlFiles = glob.sync(paths.appHtml);
124
- const envVars = getEnvVars(paths.appEnv, ifMin, ifCore, ifLocalCore);
68
+ const appEnvFiles = glob.sync(paths.appEnv);
69
+ const envVars = getEnvVars(appEnvFiles, ifMin, ifCore, ifLocalCore);
125
70
  const { ifHmr } = getIfUtils({ hmr: process.env.HMR_ENABLED === "true" }, ["hmr"]);
126
71
  const useTailwind = ifCore() && paths.appTailwindConfig && existsSync(paths.appTailwindConfig);
127
72
  logTitle("Paths:");
@@ -132,7 +77,7 @@ var getWebpackConfig = async (env) => {
132
77
  return removeEmpty([
133
78
  ifMin({ loader: MiniCssExtractPlugin.loader }),
134
79
  ifNotMin({
135
- loader: require3.resolve("style-loader"),
80
+ loader: require2.resolve("style-loader"),
136
81
  options: {
137
82
  attributes: {
138
83
  "data-widget": process.env.ELEMENT_ATTRIBUTE_DATA_WIDGET
@@ -140,35 +85,35 @@ var getWebpackConfig = async (env) => {
140
85
  }
141
86
  }),
142
87
  {
143
- loader: require3.resolve("css-loader"),
88
+ loader: require2.resolve("css-loader"),
144
89
  options: __spreadValues({
145
90
  sourceMap: ifNotMin(),
146
91
  importLoaders: 3
147
92
  }, cssOptions)
148
93
  },
149
94
  {
150
- loader: require3.resolve("postcss-loader"),
95
+ loader: require2.resolve("postcss-loader"),
151
96
  options: {
152
97
  postcssOptions: {
153
98
  plugins: removeEmpty([
154
99
  useTailwind ? [
155
- require3.resolve("tailwindcss", {
100
+ require2.resolve("tailwindcss", {
156
101
  paths: [paths.appNodeModules]
157
102
  }),
158
103
  paths.appTailwindConfig
159
104
  ] : void 0,
160
- require3.resolve("postcss-custom-properties"),
161
- require3.resolve("autoprefixer")
105
+ require2.resolve("postcss-custom-properties"),
106
+ require2.resolve("autoprefixer")
162
107
  ])
163
108
  }
164
109
  }
165
110
  },
166
111
  {
167
- loader: require3.resolve("resolve-url-loader"),
112
+ loader: require2.resolve("resolve-url-loader"),
168
113
  options: { sourceMap: ifNotMin() }
169
114
  },
170
115
  {
171
- loader: require3.resolve("sass-loader"),
116
+ loader: require2.resolve("sass-loader"),
172
117
  options: { sourceMap: true }
173
118
  }
174
119
  ]);
@@ -213,7 +158,7 @@ var getWebpackConfig = async (env) => {
213
158
  enforce: "pre",
214
159
  exclude: /@babel\/runtime/,
215
160
  test: /\.(js|jsx|ts|tsx|css|scss)$/,
216
- use: require3.resolve("source-map-loader")
161
+ use: require2.resolve("source-map-loader")
217
162
  }),
218
163
  {
219
164
  oneOf: [
@@ -224,42 +169,42 @@ var getWebpackConfig = async (env) => {
224
169
  resolveApp("node_modules/micromark"),
225
170
  resolveApp("node_modules/decode-named-character-reference")
226
171
  ], [resolveApp("."), resolveApp("../../src")]),
227
- loader: require3.resolve("babel-loader"),
172
+ loader: require2.resolve("babel-loader"),
228
173
  options: {
229
174
  babelrc: false,
230
175
  configFile: false,
231
176
  sourceMaps: ifNotMin(),
232
177
  inputSourceMap: ifNotMin(),
233
178
  presets: [
234
- require3.resolve("@babel/preset-env"),
179
+ require2.resolve("@babel/preset-env"),
235
180
  [
236
- require3.resolve("@babel/preset-typescript"),
181
+ require2.resolve("@babel/preset-typescript"),
237
182
  {
238
183
  allowDeclareFields: true
239
184
  }
240
185
  ],
241
- require3.resolve("@babel/preset-react")
186
+ require2.resolve("@babel/preset-react")
242
187
  ],
243
188
  plugins: removeEmpty([
244
189
  [
245
- require3.resolve("@babel/plugin-transform-runtime"),
190
+ require2.resolve("@babel/plugin-transform-runtime"),
246
191
  {
247
192
  corejs: {
248
193
  version: 3,
249
194
  proposals: true
250
195
  },
251
- absoluteRuntime: dirname(require3.resolve("@babel/runtime-corejs3/package.json"))
196
+ absoluteRuntime: dirname(require2.resolve("@babel/runtime-corejs3/package.json"))
252
197
  }
253
198
  ],
254
199
  [
255
- require3.resolve("@babel/plugin-proposal-decorators"),
200
+ require2.resolve("@babel/plugin-proposal-decorators"),
256
201
  {
257
202
  legacy: true
258
203
  }
259
204
  ],
260
- require3.resolve("@babel/plugin-syntax-dynamic-import"),
261
- require3.resolve("babel-plugin-lodash"),
262
- ifHmr(require3.resolve("react-refresh/babel"))
205
+ require2.resolve("@babel/plugin-syntax-dynamic-import"),
206
+ require2.resolve("babel-plugin-lodash"),
207
+ ifHmr(require2.resolve("react-refresh/babel"))
263
208
  ])
264
209
  }
265
210
  },
@@ -280,47 +225,7 @@ var getWebpackConfig = async (env) => {
280
225
  })
281
226
  },
282
227
  {
283
- test: /\.svg$/,
284
- issuer: [/\.html$/, /\.s?css$/],
285
- type: "asset",
286
- parser: {
287
- dataUrlCondition: {
288
- maxSize: imageInlineSizeLimit
289
- }
290
- }
291
- },
292
- {
293
- test: /\.svg$/,
294
- issuer: [/\.(ts|tsx|js|jsx|md|mdx)$/],
295
- use: [
296
- {
297
- loader: require3.resolve("@svgr/webpack"),
298
- options: {
299
- svgoConfig: {
300
- plugins: [
301
- {
302
- removeHiddenElems: false,
303
- moveGroupAttrsToElems: false,
304
- collapseGroups: false
305
- }
306
- ]
307
- },
308
- prettier: false,
309
- titleProp: true,
310
- ref: true
311
- }
312
- },
313
- {
314
- loader: require3.resolve("url-loader"),
315
- options: {
316
- name: "assets/[name]-[contenthash:16].[ext]",
317
- limit: imageInlineSizeLimit
318
- }
319
- }
320
- ]
321
- },
322
- {
323
- test: /\.(png|jpe?g|webp|gif|ico|ttf|eot|woff2?)$/,
228
+ test: /\.(png|jpe?g|svg|webp|gif|ico|ttf|eot|woff2?)$/,
324
229
  type: "asset",
325
230
  parser: {
326
231
  dataUrlCondition: {
@@ -331,13 +236,13 @@ var getWebpackConfig = async (env) => {
331
236
  {
332
237
  test: /\.ya?ml$/,
333
238
  use: [
334
- { loader: require3.resolve("json-loader") },
335
- { loader: require3.resolve("yaml-loader") }
239
+ { loader: require2.resolve("json-loader") },
240
+ { loader: require2.resolve("yaml-loader") }
336
241
  ]
337
242
  },
338
243
  {
339
244
  test: /\.html$/,
340
- loader: require3.resolve("html-loader"),
245
+ loader: require2.resolve("html-loader"),
341
246
  options: {
342
247
  minimize: false
343
248
  }
@@ -375,7 +280,7 @@ var getWebpackConfig = async (env) => {
375
280
  new webpack.ProgressPlugin(),
376
281
  new ESLintPlugin({
377
282
  extensions: moduleFileExtensions,
378
- eslintPath: require3.resolve("eslint"),
283
+ eslintPath: require2.resolve("eslint"),
379
284
  cwd: paths.app,
380
285
  resolvePluginsRelativeTo: paths.app
381
286
  }),
@@ -390,7 +295,7 @@ var getWebpackConfig = async (env) => {
390
295
  new webpack.DefinePlugin(envVars.stringified),
391
296
  new ForkTsCheckerWebpackPlugin({
392
297
  typescript: {
393
- typescriptPath: require3.resolve("typescript", {
298
+ typescriptPath: require2.resolve("typescript", {
394
299
  paths: [paths.appNodeModules]
395
300
  }),
396
301
  configFile: paths.appTsConfig,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raisenow/tamaro-cli",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "author": {
5
5
  "name": "RaiseNow",
6
6
  "email": "development@raisenow.com"
@@ -31,17 +31,16 @@
31
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.180",
37
- "@types/node": "^17.0.21",
35
+ "@types/lodash": "^4.14.181",
36
+ "@types/node": "^17.0.23",
38
37
  "@types/node-notifier": "^8.0.2",
39
38
  "@types/resolve-bin": "^0.4.1",
40
39
  "@types/webpack-config-utils": "^2.3.1",
41
- "@typescript-eslint/eslint-plugin": "^5.15.0",
42
- "@typescript-eslint/parser": "^5.15.0",
40
+ "@typescript-eslint/eslint-plugin": "^5.17.0",
41
+ "@typescript-eslint/parser": "^5.17.0",
43
42
  "autoprefixer": "^10.4.4",
44
- "babel-loader": "^8.2.3",
43
+ "babel-loader": "^8.2.4",
45
44
  "babel-plugin-lodash": "^3.3.4",
46
45
  "chalk": "^5.0.1",
47
46
  "clean-webpack-plugin": "^4.0.0",
@@ -54,7 +53,7 @@
54
53
  "dotenv": "^16.0.0",
55
54
  "dotenv-expand": "^8.0.3",
56
55
  "escape-string-regexp": "^5.0.0",
57
- "eslint": "^8.11.0",
56
+ "eslint": "^8.12.0",
58
57
  "eslint-config-prettier": "^8.5.0",
59
58
  "eslint-plugin-node": "^11.1.0",
60
59
  "eslint-plugin-promise": "^6.0.0",
@@ -73,17 +72,17 @@
73
72
  "postcss": "^8.4.12",
74
73
  "postcss-custom-properties": "^12.1.5",
75
74
  "postcss-loader": "^6.2.1",
76
- "prettier": "^2.6.0",
75
+ "prettier": "^2.6.1",
77
76
  "react-refresh": "^0.11.0",
78
77
  "resolve-url-loader": "^5.0.0",
79
- "sass": "^1.49.9",
78
+ "sass": "^1.49.10",
80
79
  "sass-loader": "^12.6.0",
81
80
  "source-map-loader": "^3.0.1",
82
81
  "strip-indent": "^4.0.0",
83
82
  "style-loader": "^3.3.1",
84
83
  "tsconfig-paths-webpack-plugin": "^3.5.2",
85
84
  "tsup": "^5.12.1",
86
- "typescript": "^4.6.2",
85
+ "typescript": "^4.6.3",
87
86
  "url-loader": "^4.1.1",
88
87
  "webpack": "^5.70.0",
89
88
  "webpack-cli": "^4.9.2",
package/src/cli.ts CHANGED
@@ -50,6 +50,7 @@ cli
50
50
  false,
51
51
  )
52
52
  .option('--port <port>', 'Web server port', `${DEFAULT_PORT}`)
53
+ .option('--env <env>', 'Environment (dev, stage, prod)')
53
54
  .action(async (options: DevOptions) => {
54
55
  await dev(options)
55
56
  })
@@ -67,6 +68,7 @@ cli
67
68
  .option('--analyze', 'Generate bundle statistics to "reports" folder', false)
68
69
  .option('--serve', 'Run the generated bundle with a local web server', false)
69
70
  .option('--port <port>', 'Web server port', `${DEFAULT_PORT}`)
71
+ .option('--env <env>', 'Environment (dev, stage, prod)')
70
72
  .option(
71
73
  '--deploy',
72
74
  'Deploy Tamaro Core or a customer configuration bundle to AWS S3',
@@ -7,6 +7,7 @@ import {
7
7
  resolveBin,
8
8
  resolveOwn,
9
9
  } from 'lib/resolve'
10
+ import {assertEnvValid} from 'lib/env'
10
11
  import {logCommand, logTitle} from 'lib/logging'
11
12
  import {notify} from 'lib/notifier'
12
13
  import {fail, runCommandSync} from 'lib/command'
@@ -19,6 +20,7 @@ export type BuildOptions = {
19
20
  analyze: boolean
20
21
  serve: boolean
21
22
  deploy: boolean
23
+ env: string
22
24
  }
23
25
 
24
26
  ///////////////////////////////////////////////////////////////////////////////
@@ -68,18 +70,19 @@ export const build = async (
68
70
  ///////////////////////////////////////////////////////////////////////////////
69
71
 
70
72
  const assertOptionsValid = (options: BuildOptions & DeployOptions) => {
71
- const {localCore, deploy, profile} = options
73
+ const {localCore, deploy, profile, env} = options
72
74
  const {ifCore} = getIfCoreFns()
73
75
 
74
76
  if (ifCore() && localCore) {
75
- 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.')
76
78
  }
77
79
 
78
80
  if (localCore && deploy) {
79
- fail('Flags "--local-core" and "--deploy" must not be used together.')
81
+ fail('Flags “--local-core and “--deploy must not be used together.')
80
82
  }
81
83
 
82
84
  assertProfileValid(profile)
85
+ assertEnvValid(env)
83
86
  }
84
87
 
85
88
  ///////////////////////////////////////////////////////////////////////////////
@@ -91,7 +91,7 @@ const assertBucketValid = (tag: string) => {
91
91
  const regex = /^[a-zA-Z0-9-_]+$/
92
92
 
93
93
  if (!regex.test(tag)) {
94
- fail(`Flag "--bucket" has forbidden format. Allowed format: ${regex}.`)
94
+ fail(`Flag “--bucket has forbidden format. Allowed format: ${regex}.`)
95
95
  }
96
96
  }
97
97
 
@@ -153,7 +153,7 @@ const assertTagValid = (tag: string) => {
153
153
  const regex = /^[a-zA-Z0-9-_.]+$/
154
154
 
155
155
  if (!regex.test(tag)) {
156
- fail(`Flag "--tag" has forbidden format. Allowed format: ${regex}.`)
156
+ fail(`Flag “--tag has forbidden format. Allowed format: ${regex}.`)
157
157
  }
158
158
  }
159
159
 
@@ -2,12 +2,14 @@ import {getPortPromise} from 'portfinder'
2
2
  import {getIfCoreFns, resolveBin, resolveOwn} from 'lib/resolve'
3
3
  import {logCommand, logTitle} from 'lib/logging'
4
4
  import {fail, runCommandSync} from 'lib/command'
5
+ import {assertEnvValid} from 'lib/env'
5
6
 
6
7
  ///////////////////////////////////////////////////////////////////////////////
7
8
 
8
9
  export type DevOptions = {
9
10
  localCore: boolean
10
11
  port: string
12
+ env: string
11
13
  }
12
14
 
13
15
  ///////////////////////////////////////////////////////////////////////////////
@@ -37,16 +39,18 @@ export const dev = async (options: DevOptions): Promise<void> => {
37
39
  ///////////////////////////////////////////////////////////////////////////////
38
40
 
39
41
  const assertOptionsValid = (options: DevOptions) => {
40
- const {localCore, port} = options
42
+ const {localCore, port, env} = options
41
43
  const {ifCore} = getIfCoreFns()
42
44
 
43
45
  if (ifCore() && localCore) {
44
- fail('Flag "--local-core" is redundant if running in Tamaro Core context.')
46
+ fail('Flag “--local-core is redundant if running in Tamaro Core context.')
45
47
  }
46
48
 
47
49
  if (isNaN(Number(port))) {
48
- fail('Flag "--port" should be a number.')
50
+ fail('Flag “--port should be a number.')
49
51
  }
52
+
53
+ assertEnvValid(env)
50
54
  }
51
55
 
52
56
  ///////////////////////////////////////////////////////////////////////////////
@@ -88,7 +88,7 @@ const assertConfigValid = (config: string | undefined) => {
88
88
  const regex = /^[a-zA-Z0-9-_]+$/
89
89
 
90
90
  if (!regex.test(config)) {
91
- fail(`Flag "--config" has forbidden format. Allowed format: ${regex}.`)
91
+ fail(`Flag “--config has forbidden format. Allowed format: ${regex}.`)
92
92
  }
93
93
  }
94
94
 
package/src/lib/env.ts CHANGED
@@ -1,8 +1,12 @@
1
1
  import {createRequire} from 'module'
2
+ import {basename} from 'path'
3
+ import glob from 'glob'
2
4
  import type {IfUtilsFn} from 'webpack-config-utils'
3
5
  import {expand as dotenvExpand} from 'dotenv-expand'
4
6
  import {config as dotenvConfig} from 'dotenv'
5
- import {getWidgetUuid, resolveApp} from 'lib/resolve'
7
+ import stripIndent from 'strip-indent'
8
+ import {getIfCoreFns, getPaths, getWidgetUuid, resolveApp} from 'lib/resolve'
9
+ import {fail} from 'lib/command'
6
10
 
7
11
  ///////////////////////////////////////////////////////////////////////////////
8
12
 
@@ -17,11 +21,13 @@ const require = createRequire(import.meta.url)
17
21
  ///////////////////////////////////////////////////////////////////////////////
18
22
 
19
23
  export const getEnvVars = (
20
- filePath: string,
24
+ files: string[],
21
25
  ifMin: IfUtilsFn,
22
26
  ifCore: IfUtilsFn,
23
27
  ifLocalCore: IfUtilsFn,
24
28
  ) => {
29
+ const filePath = files.find((file) => basename(file) === '.env')
30
+
25
31
  dotenvExpand(dotenvConfig({path: filePath}))
26
32
 
27
33
  process.env.NODE_ENV ??= ifMin('production', 'development')
@@ -32,6 +38,7 @@ export const getEnvVars = (
32
38
  'rnw-tamaro',
33
39
  )
34
40
  process.env.WEBPACK_UNIQUE_NAME ??= ifCore('RnwTamaroCore', 'RnwTamaro')
41
+ process.env.BUILD_DATE = new Date().toISOString()
35
42
 
36
43
  // HMR doesn't work in ie11, it breaks everything.
37
44
  // If you want to run dev-server and test in ie11, set HMR_ENABLED to 'false'
@@ -68,6 +75,7 @@ export const getEnvVars = (
68
75
  'EXPOSE_VAR',
69
76
  'ELEMENT_ATTRIBUTE_DATA_WIDGET',
70
77
  'WEBPACK_UNIQUE_NAME',
78
+ 'BUILD_DATE',
71
79
 
72
80
  // core
73
81
  'PRODUCT_NAME',
@@ -100,3 +108,38 @@ export const getEnvVars = (
100
108
 
101
109
  return {raw, stringified}
102
110
  }
111
+
112
+ ///////////////////////////////////////////////////////////////////////////////
113
+
114
+ export const assertEnvValid = (env: string) => {
115
+ const {ifCore} = getIfCoreFns()
116
+ const paths = getPaths(ifCore)
117
+ const files = glob.sync(paths.appEnv)
118
+ const envs = files
119
+ .map((file) => basename(file).replace(/^\.env\.?/, ''))
120
+ .filter((v) => !!v)
121
+
122
+ if (envs.length === 0) {
123
+ if (env) {
124
+ console.log('Flag “--env” is ignored.')
125
+ }
126
+ }
127
+
128
+ if (envs.length !== 0) {
129
+ if (!env) {
130
+ fail('Flag “--env” is required.')
131
+ }
132
+
133
+ if (!envs.includes(env)) {
134
+ fail(
135
+ stripIndent(`
136
+ Flag “--env” has wrong value.
137
+ Available values are: ${envs.map((v) => `“${v}”`).join(', ')}.
138
+ `),
139
+ )
140
+ }
141
+
142
+ const filePath = files.find((file) => basename(file) === `.env.${env}`)
143
+ dotenvExpand(dotenvConfig({path: filePath}))
144
+ }
145
+ }
@@ -72,7 +72,7 @@ export const getPaths = (ifCore: IfUtilsFn) => {
72
72
  appNodeModules: resolveApp('node_modules'),
73
73
  appTsConfig: resolveApp('tsconfig.json'),
74
74
  appHtml: resolveApp('src/*.html'),
75
- appEnv: resolveApp('.env'),
75
+ appEnv: resolveApp('.env*'),
76
76
  appTailwindConfig: resolveApp('tailwind.config.js'),
77
77
  },
78
78
  {
@@ -82,7 +82,7 @@ export const getPaths = (ifCore: IfUtilsFn) => {
82
82
  appNodeModules: resolveApp('../../node_modules'),
83
83
  appTsConfig: resolveApp('tsconfig.json'),
84
84
  appHtml: resolveApp('*.html'),
85
- appEnv: resolveApp('.env'),
85
+ appEnv: resolveApp('.env*'),
86
86
  appTailwindConfig: undefined,
87
87
  },
88
88
  )
@@ -44,7 +44,8 @@ const getWebpackConfig = async (env: any): Promise<Configuration> => {
44
44
  const {ifCore} = getIfCoreFns()
45
45
  const paths = getPaths(ifCore)
46
46
  const appHtmlFiles = glob.sync(paths.appHtml)
47
- const envVars = getEnvVars(paths.appEnv, ifMin, ifCore, ifLocalCore)
47
+ const appEnvFiles = glob.sync(paths.appEnv)
48
+ const envVars = getEnvVars(appEnvFiles, ifMin, ifCore, ifLocalCore)
48
49
  const {ifHmr} = getIfUtils({hmr: process.env.HMR_ENABLED === 'true'}, ['hmr'])
49
50
  const useTailwind =
50
51
  ifCore() && paths.appTailwindConfig && existsSync(paths.appTailwindConfig)
@@ -231,53 +232,9 @@ const getWebpackConfig = async (env: any): Promise<Configuration> => {
231
232
  }),
232
233
  },
233
234
 
234
- // SVG (in HTML and styles)
235
- {
236
- test: /\.svg$/,
237
- issuer: [/\.html$/, /\.s?css$/],
238
- type: 'asset',
239
- parser: {
240
- dataUrlCondition: {
241
- maxSize: imageInlineSizeLimit,
242
- },
243
- },
244
- },
245
-
246
- // SVG (in components)
247
- {
248
- test: /\.svg$/,
249
- issuer: [/\.(ts|tsx|js|jsx|md|mdx)$/],
250
- use: [
251
- {
252
- loader: require.resolve('@svgr/webpack'),
253
- options: {
254
- svgoConfig: {
255
- plugins: [
256
- {
257
- removeHiddenElems: false,
258
- moveGroupAttrsToElems: false,
259
- collapseGroups: false,
260
- },
261
- ],
262
- },
263
- prettier: false,
264
- titleProp: true,
265
- ref: true,
266
- },
267
- },
268
- {
269
- loader: require.resolve('url-loader'),
270
- options: {
271
- name: 'assets/[name]-[contenthash:16].[ext]',
272
- limit: imageInlineSizeLimit,
273
- },
274
- },
275
- ],
276
- },
277
-
278
235
  // Images and fonts
279
236
  {
280
- test: /\.(png|jpe?g|webp|gif|ico|ttf|eot|woff2?)$/,
237
+ test: /\.(png|jpe?g|svg|webp|gif|ico|ttf|eot|woff2?)$/,
281
238
  type: 'asset',
282
239
  parser: {
283
240
  dataUrlCondition: {