@raisenow/tamaro-cli 1.0.11 → 1.0.14

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/.nvmrc CHANGED
@@ -1 +1 @@
1
- 16.14.0
1
+ 16.14.2
package/.prettierrc.cjs CHANGED
@@ -15,4 +15,5 @@ module.exports = {
15
15
  htmlWhitespaceSensitivity: 'strict',
16
16
  endOfLine: 'lf',
17
17
  embeddedLanguageFormatting: 'auto',
18
+ singleAttributePerLine: false,
18
19
  }
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,109 @@ 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, _o, _p;
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).PUBLIC_URL) != null ? _l : _k.PUBLIC_URL = "";
163
+ (_n = (_m = process.env).HMR_ENABLED) != null ? _n : _m.HMR_ENABLED = ifMin("false", "true");
164
+ if (ifCore()) {
165
+ process.env.PRODUCT_NAME = "tamaro";
166
+ const corePkgPath = resolveApp("package.json");
167
+ const { version } = require3(corePkgPath);
168
+ process.env.PRODUCT_VERSION = version;
169
+ }
170
+ if (!ifCore()) {
171
+ process.env.WIDGET_UUID = getWidgetUuid();
172
+ if (ifLocalCore()) {
173
+ process.env.CORE_URL = `http://0.0.0.0:1234/index.js`;
174
+ } else {
175
+ let version = process.env.CORE_VERSION;
176
+ version = version ? `@${version}` : "";
177
+ (_p = (_o = process.env).CORE_URL) != null ? _p : _o.CORE_URL = `https://cdn.jsdelivr.net/npm/@raisenow/tamaro-core${version}/dist/index.js`;
178
+ }
179
+ }
180
+ const varNames = [
181
+ "NODE_ENV",
182
+ "BABEL_ENV",
183
+ "EXPOSE_VAR",
184
+ "ELEMENT_ATTRIBUTE_DATA_WIDGET",
185
+ "WEBPACK_UNIQUE_NAME",
186
+ "BUILD_DATE",
187
+ "PUBLIC_URL",
188
+ "PRODUCT_NAME",
189
+ "PRODUCT_VERSION",
190
+ "WIDGET_UUID",
191
+ "CORE_URL",
192
+ "CORE_VERSION",
193
+ "IS_CREDIT_CARD_IFRAME"
194
+ ];
195
+ const raw = Object.keys(process.env).filter((key) => /^PUBLIC_/.test(key) || varNames.includes(key)).reduce((env, key) => {
196
+ env[key] = process.env[key];
197
+ return env;
198
+ }, {});
199
+ const stringified = {
200
+ "process.env": Object.keys(raw).reduce((env, key) => {
201
+ env[key] = JSON.stringify(raw[key]);
202
+ return env;
203
+ }, {})
204
+ };
205
+ return { raw, stringified };
206
+ };
207
+ var assertEnvValid = (env) => {
208
+ const { ifCore } = getIfCoreFns();
209
+ const paths = getPaths(ifCore);
210
+ const files = glob.sync(paths.appEnv);
211
+ const envs = files.map((file) => basename2(file).replace(/^\.env\.?/, "")).filter((v) => !!v);
212
+ if (envs.length === 0) {
213
+ if (env) {
214
+ console.log("Flag \u201C--env\u201D is ignored.");
215
+ }
216
+ }
217
+ if (envs.length !== 0) {
218
+ if (!env) {
219
+ fail("Flag \u201C--env\u201D is required.");
220
+ }
221
+ if (!envs.includes(env)) {
222
+ fail(stripIndent3(`
223
+ Flag \u201C--env\u201D has wrong value.
224
+ Available values are: ${envs.map((v) => `\u201C${v}\u201D`).join(", ")}.
225
+ `));
226
+ }
227
+ const filePath = files.find((file) => basename2(file) === `.env.${env}`);
228
+ dotenvExpand(dotenvConfig({ path: filePath }));
229
+ }
230
+ };
231
+
129
232
  export {
130
233
  __spreadValues,
131
234
  logTitle,
@@ -140,5 +243,9 @@ export {
140
243
  getWidgetUuid,
141
244
  getPaths,
142
245
  getRelativePaths,
143
- getIfCoreFns
246
+ getIfCoreFns,
247
+ fail,
248
+ runCommandSync,
249
+ getEnvVars,
250
+ assertEnvValid
144
251
  };
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-IBQ4UW3S.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.11";
22
+ var version = "1.0.14";
20
23
  var author = {
21
24
  name: "RaiseNow",
22
25
  email: "development@raisenow.com"
@@ -36,76 +39,75 @@ var engines = {
36
39
  npm: ">=8"
37
40
  };
38
41
  var dependencies = {
39
- "@babel/cli": "^7.17.3",
40
- "@babel/core": "^7.17.5",
41
- "@babel/plugin-proposal-decorators": "^7.17.2",
42
+ "@babel/cli": "^7.17.6",
43
+ "@babel/core": "^7.17.9",
44
+ "@babel/plugin-proposal-decorators": "^7.17.9",
42
45
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
43
46
  "@babel/plugin-transform-runtime": "^7.17.0",
44
47
  "@babel/preset-env": "^7.16.11",
45
48
  "@babel/preset-react": "^7.16.7",
46
49
  "@babel/preset-typescript": "^7.16.7",
47
- "@babel/runtime-corejs3": "^7.17.2",
48
- "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4",
50
+ "@babel/runtime-corejs3": "^7.17.9",
51
+ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
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.178",
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.12.0",
58
- "@typescript-eslint/parser": "^5.12.0",
59
- autoprefixer: "^10.4.2",
60
- "babel-loader": "^8.2.3",
59
+ "@typescript-eslint/eslint-plugin": "^5.19.0",
60
+ "@typescript-eslint/parser": "^5.19.0",
61
+ autoprefixer: "^10.4.4",
62
+ "babel-loader": "^8.2.4",
61
63
  "babel-plugin-lodash": "^3.3.4",
62
- chalk: "^5.0.0",
64
+ chalk: "^5.0.1",
63
65
  "clean-webpack-plugin": "^4.0.0",
64
66
  columnify: "^1.6.0",
65
- commander: "^9.0.0",
67
+ commander: "^9.1.0",
66
68
  "copy-webpack-plugin": "^10.2.4",
67
69
  "core-js": "^3.21.1",
68
- "css-loader": "^6.6.0",
70
+ "css-loader": "^6.7.1",
69
71
  "css-minimizer-webpack-plugin": "^3.4.1",
70
72
  dotenv: "^16.0.0",
71
- "dotenv-expand": "^8.0.1",
73
+ "dotenv-expand": "^8.0.3",
72
74
  "escape-string-regexp": "^5.0.0",
73
- eslint: "^8.9.0",
74
- "eslint-config-prettier": "^8.4.0",
75
+ eslint: "^8.13.0",
76
+ "eslint-config-prettier": "^8.5.0",
75
77
  "eslint-plugin-node": "^11.1.0",
76
78
  "eslint-plugin-promise": "^6.0.0",
77
79
  "eslint-webpack-plugin": "^3.1.1",
78
80
  execa: "^6.1.0",
79
81
  "file-loader": "^6.2.0",
80
- "fork-ts-checker-webpack-plugin": "^7.2.1",
81
- glob: "^7.2.0",
82
+ "fork-ts-checker-webpack-plugin": "^7.2.4",
83
+ glob: "^8.0.1",
82
84
  "html-loader": "^3.1.0",
83
85
  "html-webpack-plugin": "^5.5.0",
84
86
  "json-loader": "^0.5.7",
85
87
  lodash: "^4.17.21",
86
- "mini-css-extract-plugin": "^2.5.3",
88
+ "mini-css-extract-plugin": "^2.6.0",
87
89
  "node-notifier": "^10.0.1",
88
90
  portfinder: "^1.0.28",
89
- postcss: "^8.4.6",
90
- "postcss-custom-properties": "^12.1.4",
91
+ postcss: "^8.4.12",
92
+ "postcss-custom-properties": "^12.1.7",
91
93
  "postcss-loader": "^6.2.1",
92
- prettier: "^2.5.1",
93
- "react-refresh": "^0.11.0",
94
+ prettier: "^2.6.2",
95
+ "react-refresh": "^0.12.0",
94
96
  "resolve-url-loader": "^5.0.0",
95
- sass: "^1.49.8",
97
+ sass: "^1.50.0",
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
- tsup: "^5.11.13",
102
- typescript: "^4.5.5",
103
+ tsup: "^5.12.5",
104
+ typescript: "^4.6.3",
103
105
  "url-loader": "^4.1.1",
104
- webpack: "^5.69.1",
106
+ webpack: "^5.72.0",
105
107
  "webpack-cli": "^4.9.2",
106
108
  "webpack-config-utils": "^2.3.1",
107
- "webpack-dev-server": "^4.7.4",
108
- "yaml-loader": "^0.6.0"
109
+ "webpack-dev-server": "^4.8.1",
110
+ "yaml-loader": "^0.7.0"
109
111
  };
110
112
  var package_default = {
111
113
  name,
@@ -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;
@@ -330,8 +319,8 @@ var deploy = async (options) => {
330
319
  const entryFilename = ifCore("index.js", "widget.js");
331
320
  const cmdSyncAll = `
332
321
  aws s3 sync ${paths.appDist} ${deployUrl}
322
+ --quiet
333
323
  --acl public-read
334
- --size-only
335
324
  --exclude ${paths.appDist}/${entryFilename}
336
325
  --cache-control max-age=31536000
337
326
  ${flags}
@@ -345,6 +334,7 @@ var deploy = async (options) => {
345
334
  }
346
335
  const cmdCpEntry = `
347
336
  aws s3 cp ${paths.appDist}/${entryFilename} ${deployUrl}/${entryFilename}
337
+ --quiet
348
338
  --acl public-read
349
339
  --cache-control max-age=64800
350
340
  ${flags}
@@ -403,7 +393,7 @@ var assertDistPathExists = (distPath) => {
403
393
  var assertTagValid = (tag) => {
404
394
  const regex = /^[a-zA-Z0-9-_.]+$/;
405
395
  if (!regex.test(tag)) {
406
- fail(`Flag "--tag" has forbidden format. Allowed format: ${regex}.`);
396
+ fail(`Flag \u201C--tag\u201D has forbidden format. Allowed format: ${regex}.`);
407
397
  }
408
398
  };
409
399
  var prepareFlags4 = (flags, options) => {
@@ -485,7 +475,7 @@ var assertConfigValid = (config) => {
485
475
  }
486
476
  const regex = /^[a-zA-Z0-9-_]+$/;
487
477
  if (!regex.test(config)) {
488
- fail(`Flag "--config" has forbidden format. Allowed format: ${regex}.`);
478
+ fail(`Flag \u201C--config\u201D has forbidden format. Allowed format: ${regex}.`);
489
479
  }
490
480
  };
491
481
  var prepareFlags6 = (flags, options) => {
@@ -544,7 +534,7 @@ var assertEmailConfigPathExists = (distPath) => {
544
534
  var assertBucketValid = (tag) => {
545
535
  const regex = /^[a-zA-Z0-9-_]+$/;
546
536
  if (!regex.test(tag)) {
547
- fail(`Flag "--bucket" has forbidden format. Allowed format: ${regex}.`);
537
+ fail(`Flag \u201C--bucket\u201D has forbidden format. Allowed format: ${regex}.`);
548
538
  }
549
539
  };
550
540
  var assertIsNotCore = () => {
@@ -565,10 +555,10 @@ process.on("SIGINT", () => {
565
555
  process.exit(1);
566
556
  });
567
557
  var cli = createCommand().name(package_default.name).version(package_default.version, "-v, --version");
568
- 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) => {
569
559
  await dev(options);
570
560
  });
571
- 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) => {
572
562
  await build(options);
573
563
  if (options.serve) {
574
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-IBQ4UW3S.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";
@@ -42,7 +42,10 @@ var InterpolateHtmlPlugin = class {
42
42
  compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
43
43
  const hooks = HtmlWebpackPlugin.getHooks(compilation);
44
44
  hooks.alterAssetTagGroups.tap(PLUGIN_NAME, (assets) => {
45
- this.replacements["ENTRY"] = assets.headTags[0].attributes["src"];
45
+ var _a;
46
+ const publicUrl = (_a = this.replacements["PUBLIC_URL"]) != null ? _a : "";
47
+ const entry = assets.headTags[0].attributes["src"];
48
+ this.replacements["ENTRY"] = `${publicUrl}${entry}`;
46
49
  return assets;
47
50
  });
48
51
  hooks.afterTemplateExecution.tap(PLUGIN_NAME, (data) => {
@@ -55,64 +58,8 @@ var InterpolateHtmlPlugin = class {
55
58
  }
56
59
  };
57
60
 
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
61
  // src/webpack.config.ts
115
- var require3 = createRequire2(import.meta.url);
62
+ var require2 = createRequire(import.meta.url);
116
63
  var imageInlineSizeLimit = 0;
117
64
  var getWebpackConfig = async (env) => {
118
65
  const { ifMin, ifNotMin } = getIfUtils(env, ["min"]);
@@ -121,7 +68,8 @@ var getWebpackConfig = async (env) => {
121
68
  const { ifCore } = getIfCoreFns();
122
69
  const paths = getPaths(ifCore);
123
70
  const appHtmlFiles = glob.sync(paths.appHtml);
124
- const envVars = getEnvVars(paths.appEnv, ifMin, ifCore, ifLocalCore);
71
+ const appEnvFiles = glob.sync(paths.appEnv);
72
+ const envVars = getEnvVars(appEnvFiles, ifMin, ifCore, ifLocalCore);
125
73
  const { ifHmr } = getIfUtils({ hmr: process.env.HMR_ENABLED === "true" }, ["hmr"]);
126
74
  const useTailwind = ifCore() && paths.appTailwindConfig && existsSync(paths.appTailwindConfig);
127
75
  logTitle("Paths:");
@@ -132,7 +80,7 @@ var getWebpackConfig = async (env) => {
132
80
  return removeEmpty([
133
81
  ifMin({ loader: MiniCssExtractPlugin.loader }),
134
82
  ifNotMin({
135
- loader: require3.resolve("style-loader"),
83
+ loader: require2.resolve("style-loader"),
136
84
  options: {
137
85
  attributes: {
138
86
  "data-widget": process.env.ELEMENT_ATTRIBUTE_DATA_WIDGET
@@ -140,35 +88,35 @@ var getWebpackConfig = async (env) => {
140
88
  }
141
89
  }),
142
90
  {
143
- loader: require3.resolve("css-loader"),
91
+ loader: require2.resolve("css-loader"),
144
92
  options: __spreadValues({
145
93
  sourceMap: ifNotMin(),
146
94
  importLoaders: 3
147
95
  }, cssOptions)
148
96
  },
149
97
  {
150
- loader: require3.resolve("postcss-loader"),
98
+ loader: require2.resolve("postcss-loader"),
151
99
  options: {
152
100
  postcssOptions: {
153
101
  plugins: removeEmpty([
154
102
  useTailwind ? [
155
- require3.resolve("tailwindcss", {
103
+ require2.resolve("tailwindcss", {
156
104
  paths: [paths.appNodeModules]
157
105
  }),
158
106
  paths.appTailwindConfig
159
107
  ] : void 0,
160
- require3.resolve("postcss-custom-properties"),
161
- require3.resolve("autoprefixer")
108
+ require2.resolve("postcss-custom-properties"),
109
+ require2.resolve("autoprefixer")
162
110
  ])
163
111
  }
164
112
  }
165
113
  },
166
114
  {
167
- loader: require3.resolve("resolve-url-loader"),
115
+ loader: require2.resolve("resolve-url-loader"),
168
116
  options: { sourceMap: ifNotMin() }
169
117
  },
170
118
  {
171
- loader: require3.resolve("sass-loader"),
119
+ loader: require2.resolve("sass-loader"),
172
120
  options: { sourceMap: true }
173
121
  }
174
122
  ]);
@@ -213,7 +161,7 @@ var getWebpackConfig = async (env) => {
213
161
  enforce: "pre",
214
162
  exclude: /@babel\/runtime/,
215
163
  test: /\.(js|jsx|ts|tsx|css|scss)$/,
216
- use: require3.resolve("source-map-loader")
164
+ use: require2.resolve("source-map-loader")
217
165
  }),
218
166
  {
219
167
  oneOf: [
@@ -224,42 +172,42 @@ var getWebpackConfig = async (env) => {
224
172
  resolveApp("node_modules/micromark"),
225
173
  resolveApp("node_modules/decode-named-character-reference")
226
174
  ], [resolveApp("."), resolveApp("../../src")]),
227
- loader: require3.resolve("babel-loader"),
175
+ loader: require2.resolve("babel-loader"),
228
176
  options: {
229
177
  babelrc: false,
230
178
  configFile: false,
231
179
  sourceMaps: ifNotMin(),
232
180
  inputSourceMap: ifNotMin(),
233
181
  presets: [
234
- require3.resolve("@babel/preset-env"),
182
+ require2.resolve("@babel/preset-env"),
235
183
  [
236
- require3.resolve("@babel/preset-typescript"),
184
+ require2.resolve("@babel/preset-typescript"),
237
185
  {
238
186
  allowDeclareFields: true
239
187
  }
240
188
  ],
241
- require3.resolve("@babel/preset-react")
189
+ require2.resolve("@babel/preset-react")
242
190
  ],
243
191
  plugins: removeEmpty([
244
192
  [
245
- require3.resolve("@babel/plugin-transform-runtime"),
193
+ require2.resolve("@babel/plugin-transform-runtime"),
246
194
  {
247
195
  corejs: {
248
196
  version: 3,
249
197
  proposals: true
250
198
  },
251
- absoluteRuntime: dirname(require3.resolve("@babel/runtime-corejs3/package.json"))
199
+ absoluteRuntime: dirname(require2.resolve("@babel/runtime-corejs3/package.json"))
252
200
  }
253
201
  ],
254
202
  [
255
- require3.resolve("@babel/plugin-proposal-decorators"),
203
+ require2.resolve("@babel/plugin-proposal-decorators"),
256
204
  {
257
205
  legacy: true
258
206
  }
259
207
  ],
260
- require3.resolve("@babel/plugin-syntax-dynamic-import"),
261
- require3.resolve("babel-plugin-lodash"),
262
- ifHmr(require3.resolve("react-refresh/babel"))
208
+ require2.resolve("@babel/plugin-syntax-dynamic-import"),
209
+ require2.resolve("babel-plugin-lodash"),
210
+ ifHmr(require2.resolve("react-refresh/babel"))
263
211
  ])
264
212
  }
265
213
  },
@@ -280,8 +228,7 @@ var getWebpackConfig = async (env) => {
280
228
  })
281
229
  },
282
230
  {
283
- test: /\.svg$/,
284
- issuer: [/\.html$/, /\.s?css$/],
231
+ test: /\.(png|jpe?g|svg|webp|gif|ico|ttf|eot|woff2?)$/,
285
232
  type: "asset",
286
233
  parser: {
287
234
  dataUrlCondition: {
@@ -290,54 +237,18 @@ var getWebpackConfig = async (env) => {
290
237
  }
291
238
  },
292
239
  {
293
- test: /\.svg$/,
294
- issuer: [/\.(ts|tsx|js|jsx|md|mdx)$/],
240
+ test: /\.ya?ml$/,
295
241
  use: [
242
+ { loader: require2.resolve("json-loader") },
296
243
  {
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
- }
244
+ loader: require2.resolve("yaml-loader"),
245
+ options: { asJSON: true }
319
246
  }
320
247
  ]
321
248
  },
322
- {
323
- test: /\.(png|jpe?g|webp|gif|ico|ttf|eot|woff2?)$/,
324
- type: "asset",
325
- parser: {
326
- dataUrlCondition: {
327
- maxSize: imageInlineSizeLimit
328
- }
329
- }
330
- },
331
- {
332
- test: /\.ya?ml$/,
333
- use: [
334
- { loader: require3.resolve("json-loader") },
335
- { loader: require3.resolve("yaml-loader") }
336
- ]
337
- },
338
249
  {
339
250
  test: /\.html$/,
340
- loader: require3.resolve("html-loader"),
251
+ loader: require2.resolve("html-loader"),
341
252
  options: {
342
253
  minimize: false
343
254
  }
@@ -375,7 +286,7 @@ var getWebpackConfig = async (env) => {
375
286
  new webpack.ProgressPlugin(),
376
287
  new ESLintPlugin({
377
288
  extensions: moduleFileExtensions,
378
- eslintPath: require3.resolve("eslint"),
289
+ eslintPath: require2.resolve("eslint"),
379
290
  cwd: paths.app,
380
291
  resolvePluginsRelativeTo: paths.app
381
292
  }),
@@ -390,7 +301,7 @@ var getWebpackConfig = async (env) => {
390
301
  new webpack.DefinePlugin(envVars.stringified),
391
302
  new ForkTsCheckerWebpackPlugin({
392
303
  typescript: {
393
- typescriptPath: require3.resolve("typescript", {
304
+ typescriptPath: require2.resolve("typescript", {
394
305
  paths: [paths.appNodeModules]
395
306
  }),
396
307
  configFile: paths.appTsConfig,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raisenow/tamaro-cli",
3
- "version": "1.0.11",
3
+ "version": "1.0.14",
4
4
  "author": {
5
5
  "name": "RaiseNow",
6
6
  "email": "development@raisenow.com"
@@ -20,75 +20,74 @@
20
20
  "npm": ">=8"
21
21
  },
22
22
  "dependencies": {
23
- "@babel/cli": "^7.17.3",
24
- "@babel/core": "^7.17.5",
25
- "@babel/plugin-proposal-decorators": "^7.17.2",
23
+ "@babel/cli": "^7.17.6",
24
+ "@babel/core": "^7.17.9",
25
+ "@babel/plugin-proposal-decorators": "^7.17.9",
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.2",
32
- "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4",
31
+ "@babel/runtime-corejs3": "^7.17.9",
32
+ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
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/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.12.0",
42
- "@typescript-eslint/parser": "^5.12.0",
43
- "autoprefixer": "^10.4.2",
44
- "babel-loader": "^8.2.3",
40
+ "@typescript-eslint/eslint-plugin": "^5.19.0",
41
+ "@typescript-eslint/parser": "^5.19.0",
42
+ "autoprefixer": "^10.4.4",
43
+ "babel-loader": "^8.2.4",
45
44
  "babel-plugin-lodash": "^3.3.4",
46
- "chalk": "^5.0.0",
45
+ "chalk": "^5.0.1",
47
46
  "clean-webpack-plugin": "^4.0.0",
48
47
  "columnify": "^1.6.0",
49
- "commander": "^9.0.0",
48
+ "commander": "^9.1.0",
50
49
  "copy-webpack-plugin": "^10.2.4",
51
50
  "core-js": "^3.21.1",
52
- "css-loader": "^6.6.0",
51
+ "css-loader": "^6.7.1",
53
52
  "css-minimizer-webpack-plugin": "^3.4.1",
54
53
  "dotenv": "^16.0.0",
55
- "dotenv-expand": "^8.0.1",
54
+ "dotenv-expand": "^8.0.3",
56
55
  "escape-string-regexp": "^5.0.0",
57
- "eslint": "^8.9.0",
58
- "eslint-config-prettier": "^8.4.0",
56
+ "eslint": "^8.13.0",
57
+ "eslint-config-prettier": "^8.5.0",
59
58
  "eslint-plugin-node": "^11.1.0",
60
59
  "eslint-plugin-promise": "^6.0.0",
61
60
  "eslint-webpack-plugin": "^3.1.1",
62
61
  "execa": "^6.1.0",
63
62
  "file-loader": "^6.2.0",
64
- "fork-ts-checker-webpack-plugin": "^7.2.1",
65
- "glob": "^7.2.0",
63
+ "fork-ts-checker-webpack-plugin": "^7.2.4",
64
+ "glob": "^8.0.1",
66
65
  "html-loader": "^3.1.0",
67
66
  "html-webpack-plugin": "^5.5.0",
68
67
  "json-loader": "^0.5.7",
69
68
  "lodash": "^4.17.21",
70
- "mini-css-extract-plugin": "^2.5.3",
69
+ "mini-css-extract-plugin": "^2.6.0",
71
70
  "node-notifier": "^10.0.1",
72
71
  "portfinder": "^1.0.28",
73
- "postcss": "^8.4.6",
74
- "postcss-custom-properties": "^12.1.4",
72
+ "postcss": "^8.4.12",
73
+ "postcss-custom-properties": "^12.1.7",
75
74
  "postcss-loader": "^6.2.1",
76
- "prettier": "^2.5.1",
77
- "react-refresh": "^0.11.0",
75
+ "prettier": "^2.6.2",
76
+ "react-refresh": "^0.12.0",
78
77
  "resolve-url-loader": "^5.0.0",
79
- "sass": "^1.49.8",
78
+ "sass": "^1.50.0",
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
- "tsup": "^5.11.13",
86
- "typescript": "^4.5.5",
84
+ "tsup": "^5.12.5",
85
+ "typescript": "^4.6.3",
87
86
  "url-loader": "^4.1.1",
88
- "webpack": "^5.69.1",
87
+ "webpack": "^5.72.0",
89
88
  "webpack-cli": "^4.9.2",
90
89
  "webpack-config-utils": "^2.3.1",
91
- "webpack-dev-server": "^4.7.4",
92
- "yaml-loader": "^0.6.0"
90
+ "webpack-dev-server": "^4.8.1",
91
+ "yaml-loader": "^0.7.0"
93
92
  }
94
93
  }
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
 
@@ -42,8 +42,8 @@ export const deploy = async (options: DeployOptions): Promise<void> => {
42
42
 
43
43
  const cmdSyncAll = `
44
44
  aws s3 sync ${paths.appDist} ${deployUrl}
45
+ --quiet
45
46
  --acl public-read
46
- --size-only
47
47
  --exclude ${paths.appDist}/${entryFilename}
48
48
  --cache-control max-age=31536000
49
49
  ${flags}
@@ -66,6 +66,7 @@ export const deploy = async (options: DeployOptions): Promise<void> => {
66
66
 
67
67
  const cmdCpEntry = `
68
68
  aws s3 cp ${paths.appDist}/${entryFilename} ${deployUrl}/${entryFilename}
69
+ --quiet
69
70
  --acl public-read
70
71
  --cache-control max-age=64800
71
72
  ${flags}
@@ -152,7 +153,7 @@ const assertTagValid = (tag: string) => {
152
153
  const regex = /^[a-zA-Z0-9-_.]+$/
153
154
 
154
155
  if (!regex.test(tag)) {
155
- fail(`Flag "--tag" has forbidden format. Allowed format: ${regex}.`)
156
+ fail(`Flag “--tag has forbidden format. Allowed format: ${regex}.`)
156
157
  }
157
158
  }
158
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
 
@@ -24,7 +24,9 @@ export class InterpolateHtmlPlugin {
24
24
  const hooks = HtmlWebpackPlugin.getHooks(compilation)
25
25
 
26
26
  hooks.alterAssetTagGroups.tap(PLUGIN_NAME, (assets) => {
27
- this.replacements['ENTRY'] = assets.headTags[0].attributes['src']
27
+ const publicUrl = this.replacements['PUBLIC_URL'] ?? ''
28
+ const entry = assets.headTags[0].attributes['src']
29
+ this.replacements['ENTRY'] = `${publicUrl}${entry}`
28
30
 
29
31
  return assets
30
32
  })
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,8 @@ 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()
42
+ process.env.PUBLIC_URL ??= ''
35
43
 
36
44
  // HMR doesn't work in ie11, it breaks everything.
37
45
  // If you want to run dev-server and test in ie11, set HMR_ENABLED to 'false'
@@ -68,6 +76,8 @@ export const getEnvVars = (
68
76
  'EXPOSE_VAR',
69
77
  'ELEMENT_ATTRIBUTE_DATA_WIDGET',
70
78
  'WEBPACK_UNIQUE_NAME',
79
+ 'BUILD_DATE',
80
+ 'PUBLIC_URL',
71
81
 
72
82
  // core
73
83
  'PRODUCT_NAME',
@@ -100,3 +110,38 @@ export const getEnvVars = (
100
110
 
101
111
  return {raw, stringified}
102
112
  }
113
+
114
+ ///////////////////////////////////////////////////////////////////////////////
115
+
116
+ export const assertEnvValid = (env: string) => {
117
+ const {ifCore} = getIfCoreFns()
118
+ const paths = getPaths(ifCore)
119
+ const files = glob.sync(paths.appEnv)
120
+ const envs = files
121
+ .map((file) => basename(file).replace(/^\.env\.?/, ''))
122
+ .filter((v) => !!v)
123
+
124
+ if (envs.length === 0) {
125
+ if (env) {
126
+ console.log('Flag “--env” is ignored.')
127
+ }
128
+ }
129
+
130
+ if (envs.length !== 0) {
131
+ if (!env) {
132
+ fail('Flag “--env” is required.')
133
+ }
134
+
135
+ if (!envs.includes(env)) {
136
+ fail(
137
+ stripIndent(`
138
+ Flag “--env” has wrong value.
139
+ Available values are: ${envs.map((v) => `“${v}”`).join(', ')}.
140
+ `),
141
+ )
142
+ }
143
+
144
+ const filePath = files.find((file) => basename(file) === `.env.${env}`)
145
+ dotenvExpand(dotenvConfig({path: filePath}))
146
+ }
147
+ }
@@ -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: {
@@ -291,7 +248,10 @@ const getWebpackConfig = async (env: any): Promise<Configuration> => {
291
248
  test: /\.ya?ml$/,
292
249
  use: [
293
250
  {loader: require.resolve('json-loader')},
294
- {loader: require.resolve('yaml-loader')},
251
+ {
252
+ loader: require.resolve('yaml-loader'),
253
+ options: {asJSON: true},
254
+ },
295
255
  ],
296
256
  },
297
257