@trackunit/iris-app-webpack-plugin 0.0.173 → 0.0.177

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/CHANGELOG.md CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [0.0.177](https://github.com/Trackunit/manager/compare/iris-app-webpack-plugin/0.0.176...iris-app-webpack-plugin/0.0.177) (2024-02-09)
6
+
7
+ ### Dependency Updates
8
+
9
+ * `iris-app-api` updated to version `0.0.176`
10
+ ## [0.0.176](https://github.com/Trackunit/manager/compare/iris-app-webpack-plugin/0.0.175...iris-app-webpack-plugin/0.0.176) (2024-02-08)
11
+
12
+ ### Dependency Updates
13
+
14
+ * `iris-app-api` updated to version `0.0.175`
15
+ ## [0.0.175](https://github.com/Trackunit/manager/compare/iris-app-webpack-plugin/0.0.174...iris-app-webpack-plugin/0.0.175) (2024-02-08)
16
+
17
+ ### Dependency Updates
18
+
19
+ * `iris-app-api` updated to version `0.0.174`
20
+ ## [0.0.174](https://github.com/Trackunit/manager/compare/iris-app-webpack-plugin/0.0.173...iris-app-webpack-plugin/0.0.174) (2024-02-08)
21
+
5
22
  ## [0.0.173](https://github.com/Trackunit/manager/compare/iris-app-webpack-plugin/0.0.172...iris-app-webpack-plugin/0.0.173) (2024-02-08)
6
23
 
7
24
  ## [0.0.172](https://github.com/Trackunit/manager/compare/iris-app-webpack-plugin/0.0.171...iris-app-webpack-plugin/0.0.172) (2024-02-08)
package/README.md CHANGED
@@ -13,6 +13,16 @@ For more info and a full guide on Iris App SDK Development, please visit our [De
13
13
 
14
14
  Run through the easy getting started guide here: [Getting Started](https://developers.trackunit.com/docs/getting-started)
15
15
 
16
+ ## Debugging Iris Apps (react-devtools)
17
+ Run a global install of [react-devtools](https://www.npmjs.com/package/react-devtools).
18
+ With volta:
19
+ `volta install react-devtools`
20
+
21
+ Run react-devtools from the terminal to launch the standalone DevTools app:
22
+ `react-devtools`
23
+
24
+ React-devtools will automatically connect to whichever Iris App is running in your browser at the given moment.
25
+
16
26
  ## Trackunit
17
27
  This package was developed by Trackunit ApS.
18
28
  Trackunit is the leading SaaS-based IoT solution for the construction industry, offering an ecosystem of hardware, fleet management software & telematics.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/iris-app-webpack-plugin",
3
- "version": "0.0.173",
3
+ "version": "0.0.177",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "repository": "https://github.com/Trackunit/manager",
6
6
  "engines": {
@@ -10,7 +10,8 @@
10
10
  "@trackunit/iris-app-api": "*",
11
11
  "csp-header": "^5.2.1",
12
12
  "webpack": "5.88.1",
13
- "tslib": "^2.6.2"
13
+ "tslib": "^2.6.2",
14
+ "process": "^0.11.10"
14
15
  },
15
16
  "main": "./src/index.js",
16
17
  "type": "commonjs"
@@ -1,6 +1,6 @@
1
1
  import { IrisAppManifest } from "@trackunit/iris-app-api";
2
2
  import * as wp from "webpack";
3
- interface ITrackunitIrisAppWebpackPluginOptions {
3
+ interface TrackunitIrisAppWebpackPluginOptions {
4
4
  nxRootDir: string;
5
5
  appDir: string;
6
6
  manifest: IrisAppManifest;
@@ -12,16 +12,12 @@ export declare class TrackunitIrisAppWebpackPlugin {
12
12
  private options;
13
13
  /**
14
14
  * @param options - Plugin options
15
+ * @param {string} options.appDir - Directory path where the app resides
16
+ * @param {object} options.manifest - Object containing the app's manifest
15
17
  */
16
- constructor(options: ITrackunitIrisAppWebpackPluginOptions);
18
+ constructor(options: TrackunitIrisAppWebpackPluginOptions);
17
19
  /**
18
20
  Webpack plugin for generating a Markdown file from app manifest and index HTML file.
19
- *
20
- @class
21
- @public
22
- @param {object} options - Plugin options object
23
- @param {string} options.appDir - Directory path where the app resides
24
- @param {object} options.manifest - Object containing the app's manifest
25
21
  */
26
22
  apply(compiler: wp.Compiler): void;
27
23
  }
@@ -7,29 +7,58 @@ const crypto_1 = require("crypto");
7
7
  const csp_header_1 = require("csp-header");
8
8
  const fs = tslib_1.__importStar(require("fs"));
9
9
  const path = tslib_1.__importStar(require("path"));
10
+ const process_1 = require("process");
11
+ const RESET = "\x1b[0m";
12
+ const GREEN = "\x1b[32m";
13
+ const RED = "\x1b[31m";
14
+ const YELLOW = "\x1b[33m";
15
+ const convertTranslationKeyIfNeeded = (translationObj, srcDir) => {
16
+ if (isTranslationKey(translationObj)) {
17
+ const translationKey = translationObj.key;
18
+ const enTranslationFilePath = path.join(srcDir, "locales", "en", "translation.json");
19
+ if (!fs.existsSync(enTranslationFilePath)) {
20
+ // eslint-disable-next-line no-console
21
+ console.error(RED, ` ✨ Translation file not found for: "${translationObj.key}" looked here: ${enTranslationFilePath}`, RESET);
22
+ (0, process_1.exit)(1);
23
+ }
24
+ const enTranslations = JSON.parse(fs.readFileSync(enTranslationFilePath, "utf8"));
25
+ if (!enTranslations[translationKey]) {
26
+ // eslint-disable-next-line no-console
27
+ console.error(RED, ` ✨ Translation not found for: "${translationObj.key}" looked here: ${enTranslationFilePath}`, RESET);
28
+ (0, process_1.exit)(1);
29
+ }
30
+ iris_app_api_1.languageKeys.forEach(languageCode => {
31
+ const translationFilePath = path.join(srcDir, "locales", languageCode, "translation.json");
32
+ if (fs.existsSync(translationFilePath)) {
33
+ const translations = JSON.parse(fs.readFileSync(translationFilePath, "utf8"));
34
+ // Here we substitute the translation key with the actual translation
35
+ translationObj[languageCode] = translations[translationKey];
36
+ }
37
+ else {
38
+ // eslint-disable-next-line no-console
39
+ console.log(YELLOW, ` ✨ Warning translation file not found for: "${translationObj.key}" looked here: ${translationFilePath}`, RESET);
40
+ }
41
+ });
42
+ delete translationObj.key;
43
+ }
44
+ };
10
45
  const isTranslationKey = (object) => {
11
46
  return !!(object === null || object === void 0 ? void 0 : object.key);
12
47
  };
13
- const RESET = "\x1b[0m";
14
- const GREEN = "\x1b[32m";
15
48
  /**
16
49
  * Webpack plugin that generates a manifest.json file
17
50
  */
18
51
  class TrackunitIrisAppWebpackPlugin {
19
52
  /**
20
53
  * @param options - Plugin options
54
+ * @param {string} options.appDir - Directory path where the app resides
55
+ * @param {object} options.manifest - Object containing the app's manifest
21
56
  */
22
57
  constructor(options) {
23
58
  this.options = options;
24
59
  }
25
60
  /**
26
61
  Webpack plugin for generating a Markdown file from app manifest and index HTML file.
27
- *
28
- @class
29
- @public
30
- @param {object} options - Plugin options object
31
- @param {string} options.appDir - Directory path where the app resides
32
- @param {object} options.manifest - Object containing the app's manifest
33
62
  */
34
63
  apply(compiler) {
35
64
  const pluginName = TrackunitIrisAppWebpackPlugin.name;
@@ -45,6 +74,7 @@ class TrackunitIrisAppWebpackPlugin {
45
74
  compiler.hooks.done.tap("AfterBuildPlugin", stats => {
46
75
  if (!stats.hasErrors()) {
47
76
  setTimeout(() => {
77
+ // eslint-disable-next-line no-console
48
78
  console.log(GREEN, "\n✨ Iris App is now started, check it out ✨\nhttps://new.manager.trackunit.com/iris-sdk-portal/main#runLocal\n", RESET);
49
79
  }, 0);
50
80
  }
@@ -63,7 +93,7 @@ class TrackunitIrisAppWebpackPlugin {
63
93
  // "assets" is an object that contains all assets
64
94
  // in the compilation, the keys of the object are pathnames of the assets
65
95
  // and the values are file sources.
66
- var _a, _b;
96
+ var _a, _b, _c;
67
97
  // Iterating over all the assets and
68
98
  // generating content for our Markdown file.
69
99
  if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.manifest)) {
@@ -72,62 +102,68 @@ class TrackunitIrisAppWebpackPlugin {
72
102
  const manifest = this.options.manifest;
73
103
  const indexContents = fs.readFileSync(path.join(__dirname, "index.html"), "utf8");
74
104
  const manifestJson = this.options.manifest;
75
- manifestJson.extensions = this.options.manifest.extensions;
76
- (_b = this.options.manifest.extensions) === null || _b === void 0 ? void 0 : _b.forEach(extension => {
77
- var _a, _b, _c;
78
- const translationKey = extension.type !== "IRIS_APP_SETTINGS_EXTENSION" &&
79
- extension.type !== "WIDGET_EXTENSION" &&
80
- extension.menuItem &&
81
- extension.menuItem.name;
82
- if (translationKey) {
83
- if (isTranslationKey(translationKey)) {
84
- const menuItemName = translationKey;
85
- const menuItemNameKey = menuItemName.key;
86
- iris_app_api_1.languageKeys.forEach(langugageCode => {
87
- const translationFilePath = path.join(extension.sourceRoot, "locales", langugageCode, "translation.json");
88
- if (fs.existsSync(translationFilePath)) {
89
- const translations = JSON.parse(fs.readFileSync(translationFilePath, "utf8"));
90
- //@ts-ignore - suppressImplicitAnyIndexErrors
91
- // Here we substitute the translation key with the actual translation
92
- extension.menuItem.name[langugageCode] = translations[menuItemNameKey];
93
- }
94
- });
95
- delete menuItemName.key;
105
+ const appSrc = path.join(this.options.appDir, "src");
106
+ (_b = this.options.manifest.customFieldDefinitions) === null || _b === void 0 ? void 0 : _b.forEach(customFieldDefinition => {
107
+ if ((0, iris_app_api_1.isCustomFieldTranslationArray)(customFieldDefinition.translations)) {
108
+ const foundEn = customFieldDefinition.translations.find(translation => translation.language === "en");
109
+ if (!foundEn) {
110
+ // eslint-disable-next-line no-console
111
+ console.error(RED, ` ✨ Translation not found for language "en" you must supply the english translation for custom field: ${customFieldDefinition.key}`, RESET);
112
+ (0, process_1.exit)(1);
96
113
  }
97
114
  }
98
- const headerTranslationKey = extension.type === "WIDGET_EXTENSION" && extension.header && extension.header.name;
99
- if (headerTranslationKey) {
100
- if (isTranslationKey(headerTranslationKey)) {
101
- const menuItemName = headerTranslationKey;
102
- const menuItemNameKey = menuItemName.key;
103
- iris_app_api_1.languageKeys.forEach(langugageCode => {
104
- const translationFilePath = path.join(extension.sourceRoot, "locales", langugageCode, "translation.json");
105
- if (fs.existsSync(translationFilePath)) {
106
- const translations = JSON.parse(fs.readFileSync(translationFilePath, "utf8"));
107
- //@ts-ignore - suppressImplicitAnyIndexErrors
108
- // Here we substitute the translation key with the actual translation
109
- extension.header.name[langugageCode] = translations[menuItemNameKey];
110
- }
111
- });
112
- delete menuItemName.key;
115
+ else {
116
+ convertTranslationKeyIfNeeded(customFieldDefinition.translations.title, appSrc);
117
+ convertTranslationKeyIfNeeded(customFieldDefinition.translations.description, appSrc);
118
+ // now transform to array
119
+ const titles = customFieldDefinition.translations.title;
120
+ const descriptions = customFieldDefinition.translations
121
+ .description;
122
+ const keys = Object.keys(titles);
123
+ const foundEn = keys.indexOf("en") !== -1;
124
+ if (!foundEn) {
125
+ // eslint-disable-next-line no-console
126
+ console.error(RED, ` ✨ Translation not found for language "en" you must supply the english translation for custom field: ${customFieldDefinition.key}`, RESET);
127
+ (0, process_1.exit)(1);
113
128
  }
114
- }
115
- if (extension.type === "REPORT_EXTENSION" && isTranslationKey((_a = extension.menuItem) === null || _a === void 0 ? void 0 : _a.description)) {
116
- const description = extension.menuItem.description;
117
- const menuItemDescriptionKey = description.key;
118
- iris_app_api_1.languageKeys.forEach(langugageCode => {
119
- const translationFilePath = path.join(extension.sourceRoot, "locales", langugageCode, "translation.json");
120
- if (fs.existsSync(translationFilePath)) {
121
- const translations = JSON.parse(fs.readFileSync(translationFilePath, "utf8"));
122
- //@ts-ignore - suppressImplicitAnyIndexErrors
123
- // Here we substitute the translation key with the actual translation
124
- extension.menuItem.description[langugageCode] = translations[menuItemDescriptionKey];
129
+ const translations = [
130
+ {
131
+ language: "en",
132
+ title: titles.en,
133
+ description: descriptions.en,
134
+ },
135
+ ];
136
+ keys.forEach(language => {
137
+ if (language !== "en") {
138
+ translations.push({
139
+ language,
140
+ title: titles[language],
141
+ description: descriptions[language],
142
+ });
125
143
  }
126
144
  });
127
- delete description.key;
145
+ customFieldDefinition.translations = translations;
146
+ }
147
+ //TODO REMVOE THIS once its released
148
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
149
+ customFieldDefinition.title = customFieldDefinition.translations[0].title;
150
+ });
151
+ manifestJson.extensions = this.options.manifest.extensions;
152
+ (_c = this.options.manifest.extensions) === null || _c === void 0 ? void 0 : _c.forEach(extension => {
153
+ var _a, _b, _c, _d;
154
+ const translationKey = (extension.type !== "IRIS_APP_SETTINGS_EXTENSION" &&
155
+ extension.type !== "WIDGET_EXTENSION" &&
156
+ ((_a = extension.menuItem) === null || _a === void 0 ? void 0 : _a.name)) ||
157
+ null;
158
+ convertTranslationKeyIfNeeded(translationKey, extension.sourceRoot);
159
+ const headerTranslationKey = (extension.type === "WIDGET_EXTENSION" && extension.header && extension.header.name) || null;
160
+ convertTranslationKeyIfNeeded(headerTranslationKey, extension.sourceRoot);
161
+ if (extension.type === "REPORT_EXTENSION" && isTranslationKey((_b = extension.menuItem) === null || _b === void 0 ? void 0 : _b.description)) {
162
+ const description = extension.menuItem.description;
163
+ convertTranslationKeyIfNeeded(description, extension.sourceRoot);
128
164
  }
129
165
  if (extension.type === "ASSET_HOME_EXTENSION" || extension.type === "FLEET_EXTENSION") {
130
- if ((_b = extension.conditions) === null || _b === void 0 ? void 0 : _b.brand) {
166
+ if ((_c = extension.conditions) === null || _c === void 0 ? void 0 : _c.brand) {
131
167
  if (Array.isArray(extension.conditions.brand)) {
132
168
  extension.conditions.brand.forEach(brand => {
133
169
  if (typeof brand !== "string") {
@@ -139,7 +175,7 @@ class TrackunitIrisAppWebpackPlugin {
139
175
  extension.conditions.brand.pattern = extension.conditions.brand.pattern.toString();
140
176
  }
141
177
  }
142
- if ((_c = extension.conditions) === null || _c === void 0 ? void 0 : _c.model) {
178
+ if ((_d = extension.conditions) === null || _d === void 0 ? void 0 : _d.model) {
143
179
  if (Array.isArray(extension.conditions.model)) {
144
180
  extension.conditions.model.forEach(model => {
145
181
  if (typeof model !== "string") {
@@ -1 +1 @@
1
- {"version":3,"file":"TrackunitIrisAppWebpackPlugin.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app-webpack-plugin/src/lib/TrackunitIrisAppWebpackPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { irisAppCspInput, IrisAppManifest, languageKeys, TranslationKey, Translations } from \"@trackunit/iris-app-api\";\nimport { randomBytes } from \"crypto\";\nimport { getCSP } from \"csp-header\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as wp from \"webpack\";\n\ninterface ITrackunitIrisAppWebpackPluginOptions {\n nxRootDir: string;\n appDir: string;\n manifest: IrisAppManifest;\n}\n\nconst isTranslationKey = (object: string | Translations | TranslationKey | undefined): object is TranslationKey => {\n return !!(object as { key?: string })?.key;\n};\n\nconst RESET = \"\\x1b[0m\";\nconst GREEN = \"\\x1b[32m\";\n/**\n * Webpack plugin that generates a manifest.json file\n */\nexport class TrackunitIrisAppWebpackPlugin {\n /**\n * @param options - Plugin options\n */\n public constructor(private options: ITrackunitIrisAppWebpackPluginOptions) {}\n\n /**\n Webpack plugin for generating a Markdown file from app manifest and index HTML file.\n *\n @class\n @public\n @param {object} options - Plugin options object\n @param {string} options.appDir - Directory path where the app resides\n @param {object} options.manifest - Object containing the app's manifest\n */\n public apply(compiler: wp.Compiler) {\n const pluginName = TrackunitIrisAppWebpackPlugin.name;\n\n // webpack module instance can be accessed from the compiler object,\n // this ensures that correct version of the module is used\n // (do not require/import the webpack or any symbols from it directly).\n const { webpack } = compiler;\n\n // Compilation object gives us reference to some useful constants.\n const { Compilation } = webpack;\n\n // RawSource is one of the \"sources\" classes that should be used\n // to represent asset sources in compilation.\n const { RawSource } = webpack.sources;\n\n compiler.hooks.done.tap(\"AfterBuildPlugin\", stats => {\n if (!stats.hasErrors()) {\n setTimeout(() => {\n console.log(\n GREEN,\n \"\\n✨ Iris App is now started, check it out ✨\\nhttps://new.manager.trackunit.com/iris-sdk-portal/main#runLocal\\n\",\n RESET\n );\n }, 0);\n }\n });\n\n // Tapping to the \"thisCompilation\" hook in order to further tap\n // to the compilation process on an earlier stage.\n compiler.hooks.thisCompilation.tap(pluginName, (compilation: wp.Compilation) => {\n // Tapping to the assets processing pipeline on a specific stage.\n compilation.contextDependencies.add(this.options.appDir);\n compilation.hooks.processAssets.tap(\n {\n name: pluginName,\n\n // Using one of the later asset processing stages to ensure\n // that all assets were already added to the compilation by other plugins.\n stage: Compilation.PROCESS_ASSETS_STAGE_DERIVED,\n },\n async assets => {\n // \"assets\" is an object that contains all assets\n // in the compilation, the keys of the object are pathnames of the assets\n // and the values are file sources.\n\n // Iterating over all the assets and\n // generating content for our Markdown file.\n if (!this.options?.manifest) {\n throw Error(\"you must provide a app manifest\");\n }\n const manifest = this.options.manifest;\n const indexContents = fs.readFileSync(path.join(__dirname, \"index.html\"), \"utf8\");\n\n const manifestJson = this.options.manifest;\n manifestJson.extensions = this.options.manifest.extensions;\n\n this.options.manifest.extensions?.forEach(extension => {\n const translationKey =\n extension.type !== \"IRIS_APP_SETTINGS_EXTENSION\" &&\n extension.type !== \"WIDGET_EXTENSION\" &&\n extension.menuItem &&\n extension.menuItem.name;\n\n if (translationKey) {\n if (isTranslationKey(translationKey)) {\n const menuItemName = translationKey;\n const menuItemNameKey = menuItemName.key;\n\n languageKeys.forEach(langugageCode => {\n const translationFilePath = path.join(\n extension.sourceRoot,\n \"locales\",\n langugageCode,\n \"translation.json\"\n );\n if (fs.existsSync(translationFilePath)) {\n const translations = JSON.parse(fs.readFileSync(translationFilePath, \"utf8\"));\n //@ts-ignore - suppressImplicitAnyIndexErrors\n // Here we substitute the translation key with the actual translation\n extension.menuItem.name[langugageCode] = translations[menuItemNameKey];\n }\n });\n delete (menuItemName as { key?: string }).key;\n }\n }\n const headerTranslationKey =\n extension.type === \"WIDGET_EXTENSION\" && extension.header && extension.header.name;\n if (headerTranslationKey) {\n if (isTranslationKey(headerTranslationKey)) {\n const menuItemName = headerTranslationKey;\n const menuItemNameKey = menuItemName.key;\n\n languageKeys.forEach(langugageCode => {\n const translationFilePath = path.join(\n extension.sourceRoot,\n \"locales\",\n langugageCode,\n \"translation.json\"\n );\n if (fs.existsSync(translationFilePath)) {\n const translations = JSON.parse(fs.readFileSync(translationFilePath, \"utf8\"));\n //@ts-ignore - suppressImplicitAnyIndexErrors\n // Here we substitute the translation key with the actual translation\n extension.header.name[langugageCode] = translations[menuItemNameKey];\n }\n });\n delete (menuItemName as { key?: string }).key;\n }\n }\n\n if (extension.type === \"REPORT_EXTENSION\" && isTranslationKey(extension.menuItem?.description)) {\n const description = extension.menuItem.description;\n const menuItemDescriptionKey = description.key;\n\n languageKeys.forEach(langugageCode => {\n const translationFilePath = path.join(\n extension.sourceRoot,\n \"locales\",\n langugageCode,\n \"translation.json\"\n );\n if (fs.existsSync(translationFilePath)) {\n const translations = JSON.parse(fs.readFileSync(translationFilePath, \"utf8\"));\n //@ts-ignore - suppressImplicitAnyIndexErrors\n // Here we substitute the translation key with the actual translation\n extension.menuItem.description[langugageCode] = translations[menuItemDescriptionKey];\n }\n });\n delete (description as { key?: string }).key;\n }\n if (extension.type === \"ASSET_HOME_EXTENSION\" || extension.type === \"FLEET_EXTENSION\") {\n if (extension.conditions?.brand) {\n if (Array.isArray(extension.conditions.brand)) {\n extension.conditions.brand.forEach(brand => {\n if (typeof brand !== \"string\") {\n brand.pattern = brand.pattern.toString();\n }\n });\n } else if (typeof extension.conditions.brand !== \"string\") {\n extension.conditions.brand.pattern = extension.conditions.brand.pattern.toString();\n }\n }\n if (extension.conditions?.model) {\n if (Array.isArray(extension.conditions.model)) {\n extension.conditions.model.forEach(model => {\n if (typeof model !== \"string\") {\n model.pattern = model.pattern.toString();\n }\n });\n } else if (typeof extension.conditions.model !== \"string\") {\n extension.conditions.model.pattern = extension.conditions.model.pattern.toString();\n }\n }\n }\n });\n\n manifestJson.extensions = this.options.manifest.extensions;\n compilation.emitAsset(\"manifest.json\", new RawSource(JSON.stringify(manifestJson, null, 2)));\n\n const packageJson = fs.readFileSync(`${this.options.appDir}/package.json`, \"utf8\");\n compilation.emitAsset(\"package.json\", new RawSource(packageJson));\n\n const scopeAndModuleNonce = randomBytes(16).toString(\"base64\");\n\n const cspInput = irisAppCspInput(manifest.validDomains, undefined, `'nonce-${scopeAndModuleNonce}'`);\n cspInput.directives[\"connect-src\"].push(\"ws://localhost:8097/\");\n const csp = getCSP(cspInput);\n let html = indexContents.replace(\"{{cspContent}}\", csp);\n\n html = html.replace(\"{{nonce}}\", scopeAndModuleNonce);\n\n html = html.replace(\"{{scope}}\", JSON.parse(packageJson).name);\n if (manifestJson.scopes) {\n html = html.replace(\"{{manifestScopes}}\", JSON.stringify(manifestJson.scopes));\n } else {\n html = html.replace(\"{{manifestScopes}}\", \"[]\");\n }\n // Adding new asset to the compilation, so it would be automatically\n // generated by the webpack in the output directory.\n compilation.emitAsset(\"index.html\", new RawSource(html));\n }\n );\n });\n }\n}\n"]}
1
+ {"version":3,"file":"TrackunitIrisAppWebpackPlugin.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app-webpack-plugin/src/lib/TrackunitIrisAppWebpackPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CustomFieldTranslationArray,\n irisAppCspInput,\n IrisAppManifest,\n isCustomFieldTranslationArray,\n languageKeys,\n TranslationKey,\n TranslationLanguageKeys,\n Translations,\n} from \"@trackunit/iris-app-api\";\nimport { randomBytes } from \"crypto\";\nimport { getCSP } from \"csp-header\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { exit } from \"process\";\nimport * as wp from \"webpack\";\n\ninterface TrackunitIrisAppWebpackPluginOptions {\n nxRootDir: string;\n appDir: string;\n manifest: IrisAppManifest;\n}\n\nconst RESET = \"\\x1b[0m\";\nconst GREEN = \"\\x1b[32m\";\nconst RED = \"\\x1b[31m\";\nconst YELLOW = \"\\x1b[33m\";\n\nconst convertTranslationKeyIfNeeded = (\n translationObj: string | Translations | TranslationKey | null | undefined,\n srcDir: string\n) => {\n if (isTranslationKey(translationObj)) {\n const translationKey = translationObj.key;\n\n const enTranslationFilePath = path.join(srcDir, \"locales\", \"en\", \"translation.json\");\n if (!fs.existsSync(enTranslationFilePath)) {\n // eslint-disable-next-line no-console\n console.error(\n RED,\n ` ✨ Translation file not found for: \"${translationObj.key}\" looked here: ${enTranslationFilePath}`,\n RESET\n );\n exit(1);\n }\n const enTranslations = JSON.parse(fs.readFileSync(enTranslationFilePath, \"utf8\"));\n if (!enTranslations[translationKey]) {\n // eslint-disable-next-line no-console\n console.error(\n RED,\n ` ✨ Translation not found for: \"${translationObj.key}\" looked here: ${enTranslationFilePath}`,\n RESET\n );\n exit(1);\n }\n\n languageKeys.forEach(languageCode => {\n const translationFilePath = path.join(srcDir, \"locales\", languageCode, \"translation.json\");\n if (fs.existsSync(translationFilePath)) {\n const translations = JSON.parse(fs.readFileSync(translationFilePath, \"utf8\"));\n // Here we substitute the translation key with the actual translation\n (translationObj as unknown as Translations)[languageCode] = translations[translationKey];\n } else {\n // eslint-disable-next-line no-console\n console.log(\n YELLOW,\n ` ✨ Warning translation file not found for: \"${translationObj.key}\" looked here: ${translationFilePath}`,\n RESET\n );\n }\n });\n delete (translationObj as { key?: string }).key;\n }\n};\n\nconst isTranslationKey = (\n object: string | Translations | TranslationKey | undefined | null\n): object is TranslationKey => {\n return !!(object as { key?: string })?.key;\n};\n\n/**\n * Webpack plugin that generates a manifest.json file\n */\nexport class TrackunitIrisAppWebpackPlugin {\n /**\n * @param options - Plugin options\n * @param {string} options.appDir - Directory path where the app resides\n * @param {object} options.manifest - Object containing the app's manifest\n */\n public constructor(private options: TrackunitIrisAppWebpackPluginOptions) {}\n\n /**\n Webpack plugin for generating a Markdown file from app manifest and index HTML file.\n */\n public apply(compiler: wp.Compiler) {\n const pluginName = TrackunitIrisAppWebpackPlugin.name;\n\n // webpack module instance can be accessed from the compiler object,\n // this ensures that correct version of the module is used\n // (do not require/import the webpack or any symbols from it directly).\n const { webpack } = compiler;\n\n // Compilation object gives us reference to some useful constants.\n const { Compilation } = webpack;\n\n // RawSource is one of the \"sources\" classes that should be used\n // to represent asset sources in compilation.\n const { RawSource } = webpack.sources;\n\n compiler.hooks.done.tap(\"AfterBuildPlugin\", stats => {\n if (!stats.hasErrors()) {\n setTimeout(() => {\n // eslint-disable-next-line no-console\n console.log(\n GREEN,\n \"\\n✨ Iris App is now started, check it out ✨\\nhttps://new.manager.trackunit.com/iris-sdk-portal/main#runLocal\\n\",\n RESET\n );\n }, 0);\n }\n });\n\n // Tapping to the \"thisCompilation\" hook in order to further tap\n // to the compilation process on an earlier stage.\n compiler.hooks.thisCompilation.tap(pluginName, (compilation: wp.Compilation) => {\n // Tapping to the assets processing pipeline on a specific stage.\n compilation.contextDependencies.add(this.options.appDir);\n compilation.hooks.processAssets.tap(\n {\n name: pluginName,\n\n // Using one of the later asset processing stages to ensure\n // that all assets were already added to the compilation by other plugins.\n stage: Compilation.PROCESS_ASSETS_STAGE_DERIVED,\n },\n async assets => {\n // \"assets\" is an object that contains all assets\n // in the compilation, the keys of the object are pathnames of the assets\n // and the values are file sources.\n\n // Iterating over all the assets and\n // generating content for our Markdown file.\n if (!this.options?.manifest) {\n throw Error(\"you must provide a app manifest\");\n }\n const manifest = this.options.manifest;\n const indexContents = fs.readFileSync(path.join(__dirname, \"index.html\"), \"utf8\");\n\n const manifestJson = this.options.manifest;\n\n const appSrc = path.join(this.options.appDir, \"src\");\n this.options.manifest.customFieldDefinitions?.forEach(customFieldDefinition => {\n if (isCustomFieldTranslationArray(customFieldDefinition.translations)) {\n const foundEn = customFieldDefinition.translations.find(translation => translation.language === \"en\");\n if (!foundEn) {\n // eslint-disable-next-line no-console\n console.error(\n RED,\n ` ✨ Translation not found for language \"en\" you must supply the english translation for custom field: ${customFieldDefinition.key}`,\n RESET\n );\n exit(1);\n }\n } else {\n convertTranslationKeyIfNeeded(customFieldDefinition.translations.title, appSrc);\n convertTranslationKeyIfNeeded(customFieldDefinition.translations.description, appSrc);\n\n // now transform to array\n\n const titles: Translations = customFieldDefinition.translations.title as unknown as Translations;\n const descriptions: Translations = customFieldDefinition.translations\n .description as unknown as Translations;\n const keys = Object.keys(titles) as TranslationLanguageKeys[];\n\n const foundEn = keys.indexOf(\"en\") !== -1;\n if (!foundEn) {\n // eslint-disable-next-line no-console\n console.error(\n RED,\n ` ✨ Translation not found for language \"en\" you must supply the english translation for custom field: ${customFieldDefinition.key}`,\n RESET\n );\n exit(1);\n }\n const translations: CustomFieldTranslationArray = [\n {\n language: \"en\",\n title: titles.en,\n description: descriptions.en,\n },\n ];\n\n keys.forEach(language => {\n if (language !== \"en\") {\n translations.push({\n language,\n title: titles[language]!,\n description: descriptions[language],\n });\n }\n });\n customFieldDefinition.translations = translations;\n }\n //TODO REMVOE THIS once its released\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (customFieldDefinition as any).title = customFieldDefinition.translations[0].title;\n });\n\n manifestJson.extensions = this.options.manifest.extensions;\n this.options.manifest.extensions?.forEach(extension => {\n const translationKey =\n (extension.type !== \"IRIS_APP_SETTINGS_EXTENSION\" &&\n extension.type !== \"WIDGET_EXTENSION\" &&\n extension.menuItem?.name) ||\n null;\n convertTranslationKeyIfNeeded(translationKey, extension.sourceRoot);\n\n const headerTranslationKey =\n (extension.type === \"WIDGET_EXTENSION\" && extension.header && extension.header.name) || null;\n convertTranslationKeyIfNeeded(headerTranslationKey, extension.sourceRoot);\n\n if (extension.type === \"REPORT_EXTENSION\" && isTranslationKey(extension.menuItem?.description)) {\n const description = extension.menuItem.description;\n convertTranslationKeyIfNeeded(description, extension.sourceRoot);\n }\n if (extension.type === \"ASSET_HOME_EXTENSION\" || extension.type === \"FLEET_EXTENSION\") {\n if (extension.conditions?.brand) {\n if (Array.isArray(extension.conditions.brand)) {\n extension.conditions.brand.forEach(brand => {\n if (typeof brand !== \"string\") {\n brand.pattern = brand.pattern.toString();\n }\n });\n } else if (typeof extension.conditions.brand !== \"string\") {\n extension.conditions.brand.pattern = extension.conditions.brand.pattern.toString();\n }\n }\n if (extension.conditions?.model) {\n if (Array.isArray(extension.conditions.model)) {\n extension.conditions.model.forEach(model => {\n if (typeof model !== \"string\") {\n model.pattern = model.pattern.toString();\n }\n });\n } else if (typeof extension.conditions.model !== \"string\") {\n extension.conditions.model.pattern = extension.conditions.model.pattern.toString();\n }\n }\n }\n });\n\n manifestJson.extensions = this.options.manifest.extensions;\n compilation.emitAsset(\"manifest.json\", new RawSource(JSON.stringify(manifestJson, null, 2)));\n\n const packageJson = fs.readFileSync(`${this.options.appDir}/package.json`, \"utf8\");\n compilation.emitAsset(\"package.json\", new RawSource(packageJson));\n\n const scopeAndModuleNonce = randomBytes(16).toString(\"base64\");\n\n const cspInput = irisAppCspInput(manifest.validDomains, undefined, `'nonce-${scopeAndModuleNonce}'`);\n cspInput.directives[\"connect-src\"].push(\"ws://localhost:8097/\");\n const csp = getCSP(cspInput);\n let html = indexContents.replace(\"{{cspContent}}\", csp);\n\n html = html.replace(\"{{nonce}}\", scopeAndModuleNonce);\n\n html = html.replace(\"{{scope}}\", JSON.parse(packageJson).name);\n if (manifestJson.scopes) {\n html = html.replace(\"{{manifestScopes}}\", JSON.stringify(manifestJson.scopes));\n } else {\n html = html.replace(\"{{manifestScopes}}\", \"[]\");\n }\n // Adding new asset to the compilation, so it would be automatically\n // generated by the webpack in the output directory.\n compilation.emitAsset(\"index.html\", new RawSource(html));\n }\n );\n });\n }\n}\n"]}