@toolsplus/nx-forge 1.3.3 → 1.5.0

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.
Files changed (32) hide show
  1. package/README.md +8 -0
  2. package/executors.json +6 -0
  3. package/package.json +4 -4
  4. package/src/executors/build/lib/patch-manifest-yml.js +1 -1
  5. package/src/executors/build/lib/patch-manifest-yml.js.map +1 -1
  6. package/src/executors/build/lib/process-custom-ui-dependencies.js +4 -3
  7. package/src/executors/build/lib/process-custom-ui-dependencies.js.map +1 -1
  8. package/src/executors/deploy/executor.js +14 -17
  9. package/src/executors/deploy/executor.js.map +1 -1
  10. package/src/executors/tunnel/executor.d.ts +14 -0
  11. package/src/executors/tunnel/executor.js +67 -0
  12. package/src/executors/tunnel/executor.js.map +1 -0
  13. package/src/executors/tunnel/lib/extract-custom-ui-projects.d.ts +11 -0
  14. package/src/executors/tunnel/lib/extract-custom-ui-projects.js +63 -0
  15. package/src/executors/tunnel/lib/extract-custom-ui-projects.js.map +1 -0
  16. package/src/executors/tunnel/lib/run-tunnel.d.ts +21 -0
  17. package/src/executors/tunnel/lib/run-tunnel.js +59 -0
  18. package/src/executors/tunnel/lib/run-tunnel.js.map +1 -0
  19. package/src/executors/tunnel/lib/wait-until-server-is-listening.d.ts +8 -0
  20. package/src/executors/tunnel/lib/wait-until-server-is-listening.js +52 -0
  21. package/src/executors/tunnel/lib/wait-until-server-is-listening.js.map +1 -0
  22. package/src/executors/tunnel/schema.d.ts +5 -0
  23. package/src/executors/tunnel/schema.json +29 -0
  24. package/src/generators/application/files/README.md +12 -2
  25. package/src/generators/application/lib/get-serve-config.js +2 -11
  26. package/src/generators/application/lib/get-serve-config.js.map +1 -1
  27. package/src/generators/init/generator.js +0 -2
  28. package/src/generators/init/generator.js.map +1 -1
  29. package/src/{executors/build/lib → utils/forge}/load-manifest-yml.d.ts +0 -0
  30. package/src/{executors/build/lib → utils/forge}/load-manifest-yml.js +0 -0
  31. package/src/utils/forge/load-manifest-yml.js.map +1 -0
  32. package/src/executors/build/lib/load-manifest-yml.js.map +0 -1
package/README.md CHANGED
@@ -159,6 +159,14 @@ That's it for the setup steps. You can now generate additional Custom UI resourc
159
159
 
160
160
  Run `nx build <forge-app-name>` to build the project. The build artifacts will be stored in the `dist/` directory.
161
161
 
162
+ ### Deploy
163
+
164
+ Run `nx deploy <forge-app-name>` to deploy the project. The build artifacts will be deployed using the Forge CLI deploy command.
165
+
166
+ ### Tunnel
167
+
168
+ Run `nx serve <forge-app-name>` to serve the project. This will start the `serve` target for all Custom UI projects defined in the app `manifest.yml` on their specified tunnel port. After that, it will start a build process in watch mode for the Forge app itself, before ultimately, starting the `forge tunnel` process for the Forge app.
169
+
162
170
  ## Further help on how to develop with Nx
163
171
 
164
172
  Visit the [Nx Documentation](https://nx.dev) to learn more.
package/executors.json CHANGED
@@ -10,6 +10,12 @@
10
10
  "implementation": "./src/executors/deploy/executor",
11
11
  "schema": "./src/executors/deploy/schema.json",
12
12
  "description": "deploy executor"
13
+ },
14
+ "tunnel": {
15
+ "implementation": "./src/executors/tunnel/executor",
16
+ "schema": "./src/executors/tunnel/schema.json",
17
+ "description": "tunnel executor"
13
18
  }
19
+
14
20
  }
15
21
  }
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@toolsplus/nx-forge",
3
- "version": "1.3.3",
3
+ "version": "1.5.0",
4
4
  "description": "Atlassian Forge plugin for Nx",
5
5
  "main": "src/index.js",
6
6
  "generators": "./generators.json",
7
7
  "executors": "./executors.json",
8
8
  "peerDependencies": {
9
- "@nrwl/node": "^15.0.0",
10
- "@nrwl/workspace": "^15.0.0"
9
+ "@nrwl/node": "^15.3.3",
10
+ "@nrwl/workspace": "^15.3.3"
11
11
  },
12
12
  "types": "./src/index.d.ts",
13
13
  "dependencies": {
14
- "@nrwl/webpack": "15.2.4",
14
+ "@nrwl/webpack": "15.3.3",
15
15
  "@forge/manifest": "4.5.1",
16
16
  "js-yaml": "4.1.0",
17
17
  "fs-extra": "10.1.0"
@@ -5,7 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const fs_1 = require("fs");
6
6
  const js_yaml_1 = require("js-yaml");
7
7
  const devkit_1 = require("@nrwl/devkit");
8
- const load_manifest_yml_1 = require("./load-manifest-yml");
8
+ const load_manifest_yml_1 = require("../../../utils/forge/load-manifest-yml");
9
9
  /**
10
10
  * Patches the output manifest.yml file to replace resource path parameters to point to the actual Custom UI build
11
11
  * artifacts instead of the Nx project reference.
@@ -1 +1 @@
1
- {"version":3,"file":"patch-manifest-yml.js","sourceRoot":"","sources":["../../../../../../../packages/forge/src/executors/build/lib/patch-manifest-yml.ts"],"names":[],"mappings":";;;;AAAA,2BAAmC;AACnC,qCAA+B;AAC/B,yCAAyD;AAIzD,2DAAsD;AAEtD;;;;;;;GAOG;AACH,SAAsB,gBAAgB,CAAC,OAA0B;;QAC/D,MAAM,YAAY,GAAG,IAAA,0BAAiB,EAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAE3E,eAAM,CAAC,IAAI,CAAC,YAAY,YAAY,KAAK,CAAC,CAAC;QAE3C,MAAM,cAAc,GAAG,MAAM,IAAA,mCAAe,EAAC,YAAY,CAAC,CAAC;QAE3D,MAAM,SAAS,GAAc,cAAc,CAAC,SAAS,IAAI,EAAE,CAAC;QAC5D,MAAM,eAAe,mCAChB,cAAc,KACjB,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,GACxE,CAAC;QAEF,MAAM,sBAAsB,GAAG,IAAA,cAAI,EAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QACzD,IAAA,kBAAa,EAAC,YAAY,EAAE,sBAAsB,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAE1E,eAAM,CAAC,IAAI,CAAC,iBAAiB,YAAY,GAAG,CAAC,CAAC;IAChD,CAAC;CAAA;AAjBD,4CAiBC;AAED,SAAS,aAAa,CACpB,YAAoB,EACpB,QAA+B;IAE/B,uCACK,QAAQ,KACX,IAAI,EAAE,GAAG,YAAY,IAAI,QAAQ,CAAC,IAAI,EAAE,IACxC;AACJ,CAAC"}
1
+ {"version":3,"file":"patch-manifest-yml.js","sourceRoot":"","sources":["../../../../../../../packages/forge/src/executors/build/lib/patch-manifest-yml.ts"],"names":[],"mappings":";;;;AAAA,2BAAmC;AACnC,qCAA+B;AAC/B,yCAAyD;AAIzD,8EAAyE;AAEzE;;;;;;;GAOG;AACH,SAAsB,gBAAgB,CAAC,OAA0B;;QAC/D,MAAM,YAAY,GAAG,IAAA,0BAAiB,EAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAE3E,eAAM,CAAC,IAAI,CAAC,YAAY,YAAY,KAAK,CAAC,CAAC;QAE3C,MAAM,cAAc,GAAG,MAAM,IAAA,mCAAe,EAAC,YAAY,CAAC,CAAC;QAE3D,MAAM,SAAS,GAAc,cAAc,CAAC,SAAS,IAAI,EAAE,CAAC;QAC5D,MAAM,eAAe,mCAChB,cAAc,KACjB,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,GACxE,CAAC;QAEF,MAAM,sBAAsB,GAAG,IAAA,cAAI,EAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QACzD,IAAA,kBAAa,EAAC,YAAY,EAAE,sBAAsB,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAE1E,eAAM,CAAC,IAAI,CAAC,iBAAiB,YAAY,GAAG,CAAC,CAAC;IAChD,CAAC;CAAA;AAjBD,4CAiBC;AAED,SAAS,aAAa,CACpB,YAAoB,EACpB,QAA+B;IAE/B,uCACK,QAAQ,KACX,IAAI,EAAE,GAAG,YAAY,IAAI,QAAQ,CAAC,IAAI,EAAE,IACxC;AACJ,CAAC"}
@@ -5,7 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const fs_extra_1 = require("fs-extra");
6
6
  const fs_1 = require("fs");
7
7
  const devkit_1 = require("@nrwl/devkit");
8
- const load_manifest_yml_1 = require("./load-manifest-yml");
8
+ const load_manifest_yml_1 = require("../../../utils/forge/load-manifest-yml");
9
9
  /**
10
10
  * Verifies that Custom UI projects are correctly linked to the Nx Forge app and copies build artifacts into the app's
11
11
  * output directory.
@@ -19,10 +19,11 @@ const load_manifest_yml_1 = require("./load-manifest-yml");
19
19
  * @param context Executor context
20
20
  */
21
21
  function processCustomUIDependencies(options, context) {
22
+ var _a;
22
23
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
23
24
  const manifestPath = (0, devkit_1.joinPathFragments)(context.root, 'apps', context.projectName, 'manifest.yml');
24
25
  const manifestSchema = yield (0, load_manifest_yml_1.loadManifestYml)(manifestPath);
25
- const resources = manifestSchema.resources || [];
26
+ const resources = (_a = manifestSchema.resources) !== null && _a !== void 0 ? _a : [];
26
27
  resources.forEach((r) => verifyAndCopyCustomUIDependency(r, context, options));
27
28
  return resources;
28
29
  });
@@ -33,7 +34,7 @@ const verifyAndCopyCustomUIDependency = (resource, context, options) => {
33
34
  const customUIProjectName = resource.path;
34
35
  const customUIProjectConfiguration = context.workspace.projects[customUIProjectName];
35
36
  if (!customUIProjectConfiguration) {
36
- throw new Error(`Nx workspace is missing project for CustomUI path ${customUIProjectName}. Make sure the Custom UI resource path references a project in your Nx workspace.`);
37
+ throw new Error(`Nx workspace is missing project for Custom UI path ${customUIProjectName}. Make sure the Custom UI resource path references a project in your Nx workspace.`);
37
38
  }
38
39
  if (!((_a = context.workspace.projects[context.projectName].implicitDependencies) === null || _a === void 0 ? void 0 : _a.includes(customUIProjectName))) {
39
40
  throw new Error(`Project ${customUIProjectName} is configured as Forge Custom UI resource but not listed as implicit dependency of the Forge project (${context.projectName}). Add ${customUIProjectName} to the 'implicitDependencies' array in this project's 'project.json', or remove the Custom UI resource from the app's manifest.yml.`);
@@ -1 +1 @@
1
- {"version":3,"file":"process-custom-ui-dependencies.js","sourceRoot":"","sources":["../../../../../../../packages/forge/src/executors/build/lib/process-custom-ui-dependencies.ts"],"names":[],"mappings":";;;;AAAA,uCAAoC;AACpC,2BAA6C;AAE7C,yCAAyD;AAIzD,2DAAsD;AAEtD;;;;;;;;;;;GAWG;AACH,SAAsB,2BAA2B,CAC/C,OAA0B,EAC1B,OAAwB;;QAExB,MAAM,YAAY,GAAG,IAAA,0BAAiB,EACpC,OAAO,CAAC,IAAI,EACZ,MAAM,EACN,OAAO,CAAC,WAAW,EACnB,cAAc,CACf,CAAC;QACF,MAAM,cAAc,GAAG,MAAM,IAAA,mCAAe,EAAC,YAAY,CAAC,CAAC;QAC3D,MAAM,SAAS,GAAc,cAAc,CAAC,SAAS,IAAI,EAAE,CAAC;QAE5D,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACtB,+BAA+B,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CACrD,CAAC;QAEF,OAAO,SAAS,CAAC;IACnB,CAAC;CAAA;AAlBD,kEAkBC;AAED,MAAM,+BAA+B,GAAG,CACtC,QAA+B,EAC/B,OAAwB,EACxB,OAA0B,EACpB,EAAE;;IACR,MAAM,mBAAmB,GAAG,QAAQ,CAAC,IAAI,CAAC;IAE1C,MAAM,4BAA4B,GAChC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IAElD,IAAI,CAAC,4BAA4B,EAAE;QACjC,MAAM,IAAI,KAAK,CACb,qDAAqD,mBAAmB,oFAAoF,CAC7J,CAAC;KACH;IAED,IACE,CAAC,CAAA,MAAA,OAAO,CAAC,SAAS,CAAC,QAAQ,CACzB,OAAO,CAAC,WAAW,CACpB,CAAC,oBAAoB,0CAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAA,EACrD;QACA,MAAM,IAAI,KAAK,CACb,WAAW,mBAAmB,0GAA0G,OAAO,CAAC,WAAW,UAAU,mBAAmB,sIAAsI,CAC/T,CAAC;KACH;IAED,MAAM,6BAA6B,GACjC,MAAA,MAAA,4BAA4B,CAAC,OAAO,CAAC,OAAO,CAAC,0CAAE,OAAO,0CAAE,UAAU,CAAC;IACrE,MAAM,qCAAqC,GAAG,IAAA,0BAAiB,EAC7D,OAAO,CAAC,IAAI,EACZ,6BAA6B,CAC9B,CAAC;IAEF,IACE,CAAC,6BAA6B;QAC9B,CAAC,IAAA,eAAU,EAAC,qCAAqC,CAAC;QAClD,IAAA,gBAAW,EAAC,qCAAqC,CAAC,CAAC,MAAM,KAAK,CAAC,EAC/D;QACA,MAAM,IAAI,KAAK,CACb,WAAW,mBAAmB,mGAAmG,CAClI,CAAC;KACH;IAED,eAAM,CAAC,IAAI,CAAC,WAAW,mBAAmB,+BAA+B,CAAC,CAAC;IAC3E,IAAA,mBAAQ,EACN,qCAAqC,EACrC,IAAA,0BAAiB,EACf,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,YAAY,EACpB,mBAAmB,CACpB,EACD,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAC;IACF,eAAM,CAAC,IAAI,CAAC,gBAAgB,mBAAmB,6BAA6B,CAAC,CAAC;AAChF,CAAC,CAAC"}
1
+ {"version":3,"file":"process-custom-ui-dependencies.js","sourceRoot":"","sources":["../../../../../../../packages/forge/src/executors/build/lib/process-custom-ui-dependencies.ts"],"names":[],"mappings":";;;;AAAA,uCAAoC;AACpC,2BAA6C;AAE7C,yCAAyD;AAIzD,8EAAyE;AAEzE;;;;;;;;;;;GAWG;AACH,SAAsB,2BAA2B,CAC/C,OAA0B,EAC1B,OAAwB;;;QAExB,MAAM,YAAY,GAAG,IAAA,0BAAiB,EACpC,OAAO,CAAC,IAAI,EACZ,MAAM,EACN,OAAO,CAAC,WAAW,EACnB,cAAc,CACf,CAAC;QACF,MAAM,cAAc,GAAG,MAAM,IAAA,mCAAe,EAAC,YAAY,CAAC,CAAC;QAC3D,MAAM,SAAS,GAAG,MAAA,cAAc,CAAC,SAAS,mCAAI,EAAE,CAAC;QAEjD,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACtB,+BAA+B,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CACrD,CAAC;QAEF,OAAO,SAAS,CAAC;;CAClB;AAlBD,kEAkBC;AAED,MAAM,+BAA+B,GAAG,CACtC,QAA+B,EAC/B,OAAwB,EACxB,OAA0B,EACpB,EAAE;;IACR,MAAM,mBAAmB,GAAG,QAAQ,CAAC,IAAI,CAAC;IAE1C,MAAM,4BAA4B,GAChC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IAElD,IAAI,CAAC,4BAA4B,EAAE;QACjC,MAAM,IAAI,KAAK,CACb,sDAAsD,mBAAmB,oFAAoF,CAC9J,CAAC;KACH;IAED,IACE,CAAC,CAAA,MAAA,OAAO,CAAC,SAAS,CAAC,QAAQ,CACzB,OAAO,CAAC,WAAW,CACpB,CAAC,oBAAoB,0CAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAA,EACrD;QACA,MAAM,IAAI,KAAK,CACb,WAAW,mBAAmB,0GAA0G,OAAO,CAAC,WAAW,UAAU,mBAAmB,sIAAsI,CAC/T,CAAC;KACH;IAED,MAAM,6BAA6B,GACjC,MAAA,MAAA,4BAA4B,CAAC,OAAO,CAAC,OAAO,CAAC,0CAAE,OAAO,0CAAE,UAAU,CAAC;IACrE,MAAM,qCAAqC,GAAG,IAAA,0BAAiB,EAC7D,OAAO,CAAC,IAAI,EACZ,6BAA6B,CAC9B,CAAC;IAEF,IACE,CAAC,6BAA6B;QAC9B,CAAC,IAAA,eAAU,EAAC,qCAAqC,CAAC;QAClD,IAAA,gBAAW,EAAC,qCAAqC,CAAC,CAAC,MAAM,KAAK,CAAC,EAC/D;QACA,MAAM,IAAI,KAAK,CACb,WAAW,mBAAmB,mGAAmG,CAClI,CAAC;KACH;IAED,eAAM,CAAC,IAAI,CAAC,WAAW,mBAAmB,+BAA+B,CAAC,CAAC;IAC3E,IAAA,mBAAQ,EACN,qCAAqC,EACrC,IAAA,0BAAiB,EACf,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,YAAY,EACpB,mBAAmB,CACpB,EACD,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAC;IACF,eAAM,CAAC,IAAI,CAAC,gBAAgB,mBAAmB,6BAA6B,CAAC,CAAC;AAChF,CAAC,CAAC"}
@@ -19,7 +19,20 @@ function runExecutor(options) {
19
19
  cwd: options.outputPath,
20
20
  stdio: [process.stdin, process.stdout, process.stderr],
21
21
  });
22
- yield onExit(deploymentProcess);
22
+ // https://2ality.com/2018/05/child-process-streams.html#waiting-for-a-child-process-to-exit-via-a-promise
23
+ yield new Promise((resolve, reject) => {
24
+ deploymentProcess.once('exit', (code) => {
25
+ if (code === 0) {
26
+ resolve(undefined);
27
+ }
28
+ else {
29
+ reject(new Error('Exit with error code: ' + code));
30
+ }
31
+ });
32
+ deploymentProcess.once('error', (err) => {
33
+ reject(err);
34
+ });
35
+ });
23
36
  devkit_1.logger.log('✅ Forge app deployed');
24
37
  return {
25
38
  success: true,
@@ -27,20 +40,4 @@ function runExecutor(options) {
27
40
  });
28
41
  }
29
42
  exports.default = runExecutor;
30
- // https://2ality.com/2018/05/child-process-streams.html#waiting-for-a-child-process-to-exit-via-a-promise
31
- function onExit(childProcess) {
32
- return new Promise((resolve, reject) => {
33
- childProcess.once('exit', (code) => {
34
- if (code === 0) {
35
- resolve(undefined);
36
- }
37
- else {
38
- reject(new Error('Exit with error code: ' + code));
39
- }
40
- });
41
- childProcess.once('error', (err) => {
42
- reject(err);
43
- });
44
- });
45
- }
46
43
  //# sourceMappingURL=executor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../packages/forge/src/executors/deploy/executor.ts"],"names":[],"mappings":";;;AAAA,iDAAoD;AACpD,yCAAsC;AAGtC,SAA8B,WAAW,CAAC,OAA8B;;QACtE,MAAM,IAAI,GAAG;YACX,QAAQ;YACR,iBAAiB,OAAO,CAAC,WAAW,EAAE;YACtC,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SAChE,CAAC;QAEF,MAAM,OAAO,GAAG,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,eAAM,CAAC,GAAG,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;QAElC,4FAA4F;QAC5F,MAAM,iBAAiB,GAAG,IAAA,qBAAK,EAAC,OAAO,EAAE,IAAI,EAAE;YAC7C,GAAG,EAAE,OAAO,CAAC,UAAU;YACvB,KAAK,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC;SACvD,CAAC,CAAC;QACH,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAEhC,eAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACnC,OAAO;YACL,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;CAAA;AAvBD,8BAuBC;AAED,0GAA0G;AAC1G,SAAS,MAAM,CAAC,YAA0B;IACxC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACzC,IAAI,IAAI,KAAK,CAAC,EAAE;gBACd,OAAO,CAAC,SAAS,CAAC,CAAC;aACpB;iBAAM;gBACL,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAAC,CAAC;aACpD;QACH,CAAC,CAAC,CAAC;QACH,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YACxC,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../packages/forge/src/executors/deploy/executor.ts"],"names":[],"mappings":";;;AAAA,iDAAsC;AACtC,yCAAsC;AAGtC,SAA8B,WAAW,CAAC,OAA8B;;QACtE,MAAM,IAAI,GAAG;YACX,QAAQ;YACR,iBAAiB,OAAO,CAAC,WAAW,EAAE;YACtC,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SAChE,CAAC;QAEF,MAAM,OAAO,GAAG,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,eAAM,CAAC,GAAG,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;QAElC,4FAA4F;QAC5F,MAAM,iBAAiB,GAAG,IAAA,qBAAK,EAAC,OAAO,EAAE,IAAI,EAAE;YAC7C,GAAG,EAAE,OAAO,CAAC,UAAU;YACvB,KAAK,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC;SACvD,CAAC,CAAC;QAEH,0GAA0G;QAC1G,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACpC,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBAC9C,IAAI,IAAI,KAAK,CAAC,EAAE;oBACd,OAAO,CAAC,SAAS,CAAC,CAAC;iBACpB;qBAAM;oBACL,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAAC,CAAC;iBACpD;YACH,CAAC,CAAC,CAAC;YACH,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;gBAC7C,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,eAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACnC,OAAO;YACL,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;CAAA;AApCD,8BAoCC"}
@@ -0,0 +1,14 @@
1
+ import { ExecutorContext } from '@nrwl/devkit';
2
+ import { TunnelExecutorOptions } from './schema';
3
+ /**
4
+ * Forge tunnel executor that serves all Custom UI projects in the manifest.yml
5
+ * on the tunnel port configured in the manifest.yml.
6
+ *
7
+ * Additionally, this will start a build process for the Forge app in watch mode
8
+ * and launch the `forge tunnel` command in the configured output directory.
9
+ *
10
+ * @see https://github.com/nrwl/nx/issues/3748#issuecomment-990980640
11
+ * @see https://gist.github.com/chrisui/a3cdf050bf18eccd499fba29b609b90a
12
+ * @see https://github.com/nrwl/nx/blob/cded83b2c5bf3e4252c03d4dbcbb5b203b0faed0/packages/webpack/src/executors/ssr-dev-server/ssr-dev-server.impl.ts
13
+ */
14
+ export default function runTunnelExecutor(options: TunnelExecutorOptions, context: ExecutorContext): Promise<any>;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const devkit_1 = require("@nrwl/devkit");
5
+ const async_iterable_1 = require("@nrwl/devkit/src/utils/async-iterable");
6
+ const run_tunnel_1 = require("./lib/run-tunnel");
7
+ const extract_custom_ui_projects_1 = require("./lib/extract-custom-ui-projects");
8
+ /**
9
+ * Forge tunnel executor that serves all Custom UI projects in the manifest.yml
10
+ * on the tunnel port configured in the manifest.yml.
11
+ *
12
+ * Additionally, this will start a build process for the Forge app in watch mode
13
+ * and launch the `forge tunnel` command in the configured output directory.
14
+ *
15
+ * @see https://github.com/nrwl/nx/issues/3748#issuecomment-990980640
16
+ * @see https://gist.github.com/chrisui/a3cdf050bf18eccd499fba29b609b90a
17
+ * @see https://github.com/nrwl/nx/blob/cded83b2c5bf3e4252c03d4dbcbb5b203b0faed0/packages/webpack/src/executors/ssr-dev-server/ssr-dev-server.impl.ts
18
+ */
19
+ function runTunnelExecutor(options, context) {
20
+ var e_1, _a;
21
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
22
+ const customUiProjectConfigs = yield (0, extract_custom_ui_projects_1.getCustomUiProjects)(context);
23
+ let runAllCustomUiServe = undefined;
24
+ if (customUiProjectConfigs.length > 0) {
25
+ const [customUiHeadConfig, ...customUiRestConfig] = customUiProjectConfigs;
26
+ // execute the serve target on custom UI projects
27
+ runAllCustomUiServe = yield (0, devkit_1.runExecutor)({ project: customUiHeadConfig.projectName, target: 'serve' }, { port: customUiHeadConfig.port }, context);
28
+ for (const { projectName, port } of customUiRestConfig !== null && customUiRestConfig !== void 0 ? customUiRestConfig : []) {
29
+ runAllCustomUiServe = (0, async_iterable_1.combineAsyncIterableIterators)(runAllCustomUiServe, yield (0, devkit_1.runExecutor)({ project: projectName, target: 'serve' }, { port }, context));
30
+ }
31
+ }
32
+ const runForgeAppBuild = yield (0, devkit_1.runExecutor)({ project: context.projectName, target: 'build' }, { watch: true }, context);
33
+ // execute the tunnel target on the focused project
34
+ const runForgeTunnel = promiseToIterator((0, run_tunnel_1.default)(Object.assign(Object.assign({}, options), { customUiProjectConfigs }), context));
35
+ // once all executors are loaded, watch out for any failures
36
+ // we combine (interleave) all executor iterators here
37
+ const combined = (0, async_iterable_1.combineAsyncIterableIterators)(runAllCustomUiServe, runForgeAppBuild, runForgeTunnel);
38
+ try {
39
+ try {
40
+ for (var combined_1 = tslib_1.__asyncValues(combined), combined_1_1; combined_1_1 = yield combined_1.next(), !combined_1_1.done;) {
41
+ const output = combined_1_1.value;
42
+ if (!output.success)
43
+ return output;
44
+ }
45
+ }
46
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
47
+ finally {
48
+ try {
49
+ if (combined_1_1 && !combined_1_1.done && (_a = combined_1.return)) yield _a.call(combined_1);
50
+ }
51
+ finally { if (e_1) throw e_1.error; }
52
+ }
53
+ }
54
+ catch (err) {
55
+ devkit_1.logger.error(`Failed to tunnel Forge app: ${err}`);
56
+ throw err;
57
+ }
58
+ return { success: true };
59
+ });
60
+ }
61
+ exports.default = runTunnelExecutor;
62
+ function promiseToIterator(v) {
63
+ return tslib_1.__asyncGenerator(this, arguments, function* promiseToIterator_1() {
64
+ yield yield tslib_1.__await(yield tslib_1.__await(v));
65
+ });
66
+ }
67
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../packages/forge/src/executors/tunnel/executor.ts"],"names":[],"mappings":";;;AAAA,yCAAoE;AACpE,0EAAsF;AAEtF,iDAAyC;AACzC,iFAAuE;AAEvE;;;;;;;;;;GAUG;AACH,SAA8B,iBAAiB,CAC7C,OAA8B,EAC9B,OAAwB;;;QAExB,MAAM,sBAAsB,GAAG,MAAM,IAAA,gDAAmB,EAAC,OAAO,CAAC,CAAC;QAClE,IAAI,mBAAmB,GAAG,SAAS,CAAC;QAEpC,IAAI,sBAAsB,CAAC,MAAM,GAAG,CAAC,EAAE;YACrC,MAAM,CAAC,kBAAkB,EAAE,GAAG,kBAAkB,CAAC,GAAG,sBAAsB,CAAC;YAE3E,iDAAiD;YACjD,mBAAmB,GAAG,MAAM,IAAA,oBAAW,EACrC,EAAE,OAAO,EAAE,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,EAC5D,EAAE,IAAI,EAAE,kBAAkB,CAAC,IAAI,EAAE,EACjC,OAAO,CACR,CAAC;YAEF,KAAK,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,kBAAkB,aAAlB,kBAAkB,cAAlB,kBAAkB,GAAI,EAAE,EAAE;gBAC5D,mBAAmB,GAAG,IAAA,8CAA6B,EACjD,mBAAmB,EACnB,MAAM,IAAA,oBAAW,EACf,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,EACzC,EAAE,IAAI,EAAE,EACR,OAAO,CACR,CACF,CAAC;aACH;SACF;QAED,MAAM,gBAAgB,GAAG,MAAM,IAAA,oBAAW,EACxC,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,EACjD,EAAE,KAAK,EAAE,IAAI,EAAE,EACf,OAAO,CACR,CAAC;QAEF,mDAAmD;QACnD,MAAM,cAAc,GAAG,iBAAiB,CACtC,IAAA,oBAAS,kCAAM,OAAO,KAAE,sBAAsB,KAAI,OAAO,CAAC,CAC3D,CAAC;QAEF,4DAA4D;QAC5D,sDAAsD;QACtD,MAAM,QAAQ,GAAG,IAAA,8CAA6B,EAC5C,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,CACf,CAAC;QAEF,IAAI;;gBACF,KAA2B,IAAA,aAAA,sBAAA,QAAQ,CAAA,cAAA;oBAAxB,MAAM,MAAM,qBAAA,CAAA;oBACrB,IAAI,CAAC,MAAM,CAAC,OAAO;wBAAE,OAAO,MAAM,CAAC;iBACpC;;;;;;;;;SACF;QAAC,OAAO,GAAG,EAAE;YACZ,eAAM,CAAC,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;YACnD,MAAM,GAAG,CAAC;SACX;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;;CAC1B;AA1DD,oCA0DC;AAED,SAAgB,iBAAiB,CAC/B,CAAa;;QAEb,4BAAM,sBAAM,CAAC,CAAA,CAAA,CAAC;IAChB,CAAC;CAAA"}
@@ -0,0 +1,11 @@
1
+ import { ExecutorContext } from '@nrwl/devkit';
2
+ /**
3
+ * Extracts all configured Custom UI resources and their tunnel port for this Forge app.
4
+ *
5
+ * @param context Executor context for this call
6
+ * @returns Custom UI project names and the tunnel port on which they are required to serve their dev server.
7
+ */
8
+ export declare function getCustomUiProjects(context: ExecutorContext): Promise<{
9
+ projectName: string;
10
+ port: number;
11
+ }[]>;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCustomUiProjects = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const devkit_1 = require("@nrwl/devkit");
6
+ const load_manifest_yml_1 = require("../../../utils/forge/load-manifest-yml");
7
+ /**
8
+ * Extracts all configured Custom UI resources and their tunnel port for this Forge app.
9
+ *
10
+ * @param context Executor context for this call
11
+ * @returns Custom UI project names and the tunnel port on which they are required to serve their dev server.
12
+ */
13
+ function getCustomUiProjects(context) {
14
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
15
+ const projects = yield extractVerifiedCustomUiProjects(context);
16
+ return projects.map((p) => ({
17
+ projectName: p.path,
18
+ port: p.tunnel.port,
19
+ }));
20
+ });
21
+ }
22
+ exports.getCustomUiProjects = getCustomUiProjects;
23
+ /**
24
+ * Extracts all Custom UI projects from the manifest.yml
25
+ *
26
+ * This will assert that:
27
+ *
28
+ * - the Nx workspace has a project configured for each Custom UI project
29
+ * - each Custom UI project has a 'serve' target
30
+ * - each Custom UI project is listed as an implicit dependency of the Forge app
31
+ * - each Custom UI resource has a configured tunnel port in the Forge app's manifest.yml
32
+ *
33
+ * @param context Executor context for this call
34
+ * @returns All configured and verified Custom UI resources
35
+ */
36
+ function extractVerifiedCustomUiProjects(context) {
37
+ var _a;
38
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
39
+ const manifestPath = (0, devkit_1.joinPathFragments)(context.root, 'apps', context.projectName, 'manifest.yml');
40
+ const manifestSchema = yield (0, load_manifest_yml_1.loadManifestYml)(manifestPath);
41
+ const resources = (_a = manifestSchema.resources) !== null && _a !== void 0 ? _a : [];
42
+ return resources.map(verifyCustomUIDependency(context));
43
+ });
44
+ }
45
+ const verifyCustomUIDependency = (context) => (resource) => {
46
+ var _a;
47
+ const customUIProjectName = resource.path;
48
+ const customUIProjectConfiguration = context.workspace.projects[customUIProjectName];
49
+ if (!customUIProjectConfiguration) {
50
+ throw new Error(`Nx workspace is missing project for Custom UI path ${customUIProjectName}. Make sure the Custom UI resource path references a project in your Nx workspace.`);
51
+ }
52
+ if (!customUIProjectConfiguration.targets['serve']) {
53
+ throw new Error(`Custom UI project '${customUIProjectName}' targets is missing a 'serve' executor. Make sure the 'targets' property in the project's 'project.json' has a 'serve' executor configured.`);
54
+ }
55
+ if (!((_a = context.workspace.projects[context.projectName].implicitDependencies) === null || _a === void 0 ? void 0 : _a.includes(customUIProjectName))) {
56
+ throw new Error(`Project ${customUIProjectName} is configured as Forge Custom UI resource but not listed as implicit dependency of the Forge project (${context.projectName}). Add ${customUIProjectName} to the 'implicitDependencies' array in this project's 'project.json', or remove the Custom UI resource from the app's manifest.yml.`);
57
+ }
58
+ if (!resource.tunnel || !Number.isInteger(resource.tunnel.port)) {
59
+ throw new Error(`Custom UI resource with key ${resource.key} is missing tunnel port in manifest.yml. Follow the Forge docs on how to add a tunnel port to the Custom UI resource with key ${resource.key}: https://developer.atlassian.com/platform/forge/tunneling/#connecting-the-tunnel-to-your-own-dev-server`);
60
+ }
61
+ return resource;
62
+ };
63
+ //# sourceMappingURL=extract-custom-ui-projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-custom-ui-projects.js","sourceRoot":"","sources":["../../../../../../../packages/forge/src/executors/tunnel/lib/extract-custom-ui-projects.ts"],"names":[],"mappings":";;;;AAAA,yCAAkE;AAGlE,8EAAyE;AAIzE;;;;;GAKG;AACH,SAAsB,mBAAmB,CACvC,OAAwB;;QAExB,MAAM,QAAQ,GAAG,MAAM,+BAA+B,CAAC,OAAO,CAAC,CAAC;QAChE,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC1B,WAAW,EAAE,CAAC,CAAC,IAAI;YACnB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI;SACpB,CAAC,CAAC,CAAC;IACN,CAAC;CAAA;AARD,kDAQC;AAED;;;;;;;;;;;;GAYG;AACH,SAAe,+BAA+B,CAC5C,OAAwB;;;QAExB,MAAM,YAAY,GAAG,IAAA,0BAAiB,EACpC,OAAO,CAAC,IAAI,EACZ,MAAM,EACN,OAAO,CAAC,WAAW,EACnB,cAAc,CACf,CAAC;QACF,MAAM,cAAc,GAAG,MAAM,IAAA,mCAAe,EAAC,YAAY,CAAC,CAAC;QAC3D,MAAM,SAAS,GAAc,MAAA,cAAc,CAAC,SAAS,mCAAI,EAAE,CAAC;QAC5D,OAAO,SAAS,CAAC,GAAG,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC;;CACzD;AAED,MAAM,wBAAwB,GAC5B,CAAC,OAAwB,EAAE,EAAE,CAC7B,CAAC,QAA+B,EAA0B,EAAE;;IAC1D,MAAM,mBAAmB,GAAG,QAAQ,CAAC,IAAI,CAAC;IAE1C,MAAM,4BAA4B,GAChC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IAElD,IAAI,CAAC,4BAA4B,EAAE;QACjC,MAAM,IAAI,KAAK,CACb,sDAAsD,mBAAmB,oFAAoF,CAC9J,CAAC;KACH;IAED,IAAI,CAAC,4BAA4B,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAClD,MAAM,IAAI,KAAK,CACb,sBAAsB,mBAAmB,8IAA8I,CACxL,CAAC;KACH;IAED,IACE,CAAC,CAAA,MAAA,OAAO,CAAC,SAAS,CAAC,QAAQ,CACzB,OAAO,CAAC,WAAW,CACpB,CAAC,oBAAoB,0CAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAA,EACrD;QACA,MAAM,IAAI,KAAK,CACb,WAAW,mBAAmB,0GAA0G,OAAO,CAAC,WAAW,UAAU,mBAAmB,sIAAsI,CAC/T,CAAC;KACH;IAED,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QAC/D,MAAM,IAAI,KAAK,CACb,+BAA+B,QAAQ,CAAC,GAAG,iIAAiI,QAAQ,CAAC,GAAG,0GAA0G,CACnS,CAAC;KACH;IAED,OAAO,QAAkC,CAAC;AAC5C,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { ExecutorContext } from '@nrwl/devkit';
2
+ import { TunnelExecutorOptions } from '../schema';
3
+ /**
4
+ * Starts the `forge tunnel` process in the app's output directory. The execution of `forge tunnel` will be delayed
5
+ * until all configured Custom UI dev servers are listening on their configured tunnel port.
6
+ *
7
+ * This will set the `FORGE_TUNNEL_MOUNT_DIRECTORIES` env variable on the tunnel process to mount the Nx workspace
8
+ * root `node_modules` folder into the tunnel container. This makes sure that the Forge bundler running in the tunnel
9
+ * Docker container knows about installed npm dependencies.
10
+ *
11
+ * @param options Tunnel executor options
12
+ * @param context Executor context for this call
13
+ */
14
+ export default function runTunnel(options: TunnelExecutorOptions & {
15
+ customUiProjectConfigs: {
16
+ projectName: string;
17
+ port: number;
18
+ }[];
19
+ }, context: ExecutorContext): Promise<{
20
+ success: boolean;
21
+ }>;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const devkit_1 = require("@nrwl/devkit");
5
+ const path_1 = require("path");
6
+ const child_process_1 = require("child_process");
7
+ const wait_until_server_is_listening_1 = require("./wait-until-server-is-listening");
8
+ /**
9
+ * Starts the `forge tunnel` process in the app's output directory. The execution of `forge tunnel` will be delayed
10
+ * until all configured Custom UI dev servers are listening on their configured tunnel port.
11
+ *
12
+ * This will set the `FORGE_TUNNEL_MOUNT_DIRECTORIES` env variable on the tunnel process to mount the Nx workspace
13
+ * root `node_modules` folder into the tunnel container. This makes sure that the Forge bundler running in the tunnel
14
+ * Docker container knows about installed npm dependencies.
15
+ *
16
+ * @param options Tunnel executor options
17
+ * @param context Executor context for this call
18
+ */
19
+ function runTunnel(options, context) {
20
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
21
+ devkit_1.logger.info(`Wait for all Custom UI 'serve' targets to have started and servers are listening...`);
22
+ yield Promise.all(options.customUiProjectConfigs.map(({ port }) => (0, wait_until_server_is_listening_1.waitUntilServerIsListening)(port, context)));
23
+ devkit_1.logger.info(`All Custom UI 'serve' targets have started and servers are listening`);
24
+ const args = [
25
+ 'tunnel',
26
+ ...(options.verbose === true ? ['--verbose'] : []),
27
+ ...(options.debug === true ? ['--debug'] : []),
28
+ ];
29
+ const command = `forge ${args.join(' ')}`;
30
+ devkit_1.logger.log(`Running: ${command}`);
31
+ // https://2ality.com/2018/05/child-process-streams.html#running-commands-in-child-processes
32
+ const tunnelProcess = (0, child_process_1.spawn)('forge', args, {
33
+ cwd: options.outputPath,
34
+ env: Object.assign(Object.assign({}, process.env), {
35
+ // Mount the root node_modules folder into the tunnel container to avoid having to npm install in the dist directory
36
+ // https://github.com/toolsplus/forge-turbo/issues/1#issue-1451384347
37
+ FORGE_TUNNEL_MOUNT_DIRECTORIES: `${(0, path_1.join)(context.root, 'node_modules')}:/app/node_modules` }),
38
+ stdio: 'inherit',
39
+ });
40
+ return new Promise((resolve, reject) => {
41
+ tunnelProcess.once('exit', (code) => {
42
+ if (code === 0) {
43
+ devkit_1.logger.info('Exiting the forge tunnel process...');
44
+ resolve({
45
+ success: true,
46
+ });
47
+ }
48
+ else {
49
+ reject(new Error('Forge tunnel process terminated with error code: ' + code));
50
+ }
51
+ });
52
+ tunnelProcess.once('error', (err) => {
53
+ reject(new Error('Forge tunnel process failed: ' + err));
54
+ });
55
+ });
56
+ });
57
+ }
58
+ exports.default = runTunnel;
59
+ //# sourceMappingURL=run-tunnel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-tunnel.js","sourceRoot":"","sources":["../../../../../../../packages/forge/src/executors/tunnel/lib/run-tunnel.ts"],"names":[],"mappings":";;;AAAA,yCAAuD;AACvD,+BAA4B;AAC5B,iDAAsC;AAEtC,qFAA8E;AAE9E;;;;;;;;;;GAUG;AACH,SAA8B,SAAS,CACrC,OAKC,EACD,OAAwB;;QAExB,eAAM,CAAC,IAAI,CACT,qFAAqF,CACtF,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAC9C,IAAA,2DAA0B,EAAC,IAAI,EAAE,OAAO,CAAC,CAC1C,CACF,CAAC;QAEF,eAAM,CAAC,IAAI,CACT,sEAAsE,CACvE,CAAC;QAEF,MAAM,IAAI,GAAG;YACX,QAAQ;YACR,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SAC/C,CAAC;QAEF,MAAM,OAAO,GAAG,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,eAAM,CAAC,GAAG,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;QAElC,4FAA4F;QAC5F,MAAM,aAAa,GAAG,IAAA,qBAAK,EAAC,OAAO,EAAE,IAAI,EAAE;YACzC,GAAG,EAAE,OAAO,CAAC,UAAU;YACvB,GAAG,kCACE,OAAO,CAAC,GAAG;gBACd,oHAAoH;gBACpH,qEAAqE;gBACrE,8BAA8B,EAAE,GAAG,IAAA,WAAI,EACrC,OAAO,CAAC,IAAI,EACZ,cAAc,CACf,oBAAoB,GACtB;YACD,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QAEH,OAAO,IAAI,OAAO,CAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3D,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBAC1C,IAAI,IAAI,KAAK,CAAC,EAAE;oBACd,eAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;oBACnD,OAAO,CAAC;wBACN,OAAO,EAAE,IAAI;qBACd,CAAC,CAAC;iBACJ;qBAAM;oBACL,MAAM,CACJ,IAAI,KAAK,CAAC,mDAAmD,GAAG,IAAI,CAAC,CACtE,CAAC;iBACH;YACH,CAAC,CAAC,CAAC;YACH,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;gBACzC,MAAM,CAAC,IAAI,KAAK,CAAC,+BAA+B,GAAG,GAAG,CAAC,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CAAA;AAhED,4BAgEC"}
@@ -0,0 +1,8 @@
1
+ import { ExecutorContext } from '@nrwl/devkit';
2
+ /**
3
+ *
4
+ * @param port Port on which the server is listening
5
+ * @param context Executor context for this invocation
6
+ * @see https://github.com/nrwl/nx/blob/cded83b2c5bf3e4252c03d4dbcbb5b203b0faed0/packages/webpack/src/executors/ssr-dev-server/lib/wait-until-server-is-listening.ts
7
+ */
8
+ export declare function waitUntilServerIsListening(port: number, context: ExecutorContext): Promise<void>;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.waitUntilServerIsListening = void 0;
4
+ const net = require("net");
5
+ const devkit_1 = require("@nrwl/devkit");
6
+ /**
7
+ *
8
+ * @param port Port on which the server is listening
9
+ * @param context Executor context for this invocation
10
+ * @see https://github.com/nrwl/nx/blob/cded83b2c5bf3e4252c03d4dbcbb5b203b0faed0/packages/webpack/src/executors/ssr-dev-server/lib/wait-until-server-is-listening.ts
11
+ */
12
+ function waitUntilServerIsListening(port, context) {
13
+ const allowedErrorCodes = ['ECONNREFUSED', 'ECONNRESET'];
14
+ const maxAttempts = 15;
15
+ let attempts = 0;
16
+ const client = new net.Socket();
17
+ const cleanup = () => {
18
+ client.removeAllListeners('connect');
19
+ client.removeAllListeners('error');
20
+ client.end();
21
+ client.destroy();
22
+ client.unref();
23
+ };
24
+ return new Promise((resolve, reject) => {
25
+ const listen = () => {
26
+ client.once('connect', () => {
27
+ cleanup();
28
+ resolve();
29
+ });
30
+ client.on('error', (err) => {
31
+ if (attempts > maxAttempts ||
32
+ !allowedErrorCodes.includes(err['code'])) {
33
+ if (context.isVerbose) {
34
+ devkit_1.logger.error(`Could not wait for server to start on port ${port}: ${attempts > maxAttempts
35
+ ? `Max attempts (${maxAttempts}) exceeded`
36
+ : `Server returned unexpected error code ${err['code']}`}`);
37
+ }
38
+ cleanup();
39
+ reject(err);
40
+ }
41
+ else {
42
+ attempts++;
43
+ setTimeout(listen, 1000 * attempts);
44
+ }
45
+ });
46
+ client.connect({ port, host: 'localhost' });
47
+ };
48
+ listen();
49
+ });
50
+ }
51
+ exports.waitUntilServerIsListening = waitUntilServerIsListening;
52
+ //# sourceMappingURL=wait-until-server-is-listening.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait-until-server-is-listening.js","sourceRoot":"","sources":["../../../../../../../packages/forge/src/executors/tunnel/lib/wait-until-server-is-listening.ts"],"names":[],"mappings":";;;AAAA,2BAA2B;AAC3B,yCAAuD;AAEvD;;;;;GAKG;AACH,SAAgB,0BAA0B,CACxC,IAAY,EACZ,OAAwB;IAExB,MAAM,iBAAiB,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IACzD,MAAM,WAAW,GAAG,EAAE,CAAC;IACvB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC,CAAC;IAEF,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;gBAC1B,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACzB,IACE,QAAQ,GAAG,WAAW;oBACtB,CAAC,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EACxC;oBACA,IAAI,OAAO,CAAC,SAAS,EAAE;wBACrB,eAAM,CAAC,KAAK,CACV,8CAA8C,IAAI,KAChD,QAAQ,GAAG,WAAW;4BACpB,CAAC,CAAC,iBAAiB,WAAW,YAAY;4BAC1C,CAAC,CAAC,yCAAyC,GAAG,CAAC,MAAM,CAAC,EAC1D,EAAE,CACH,CAAC;qBACH;oBACD,OAAO,EAAE,CAAC;oBACV,MAAM,CAAC,GAAG,CAAC,CAAC;iBACb;qBAAM;oBACL,QAAQ,EAAE,CAAC;oBACX,UAAU,CAAC,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAC,CAAC;iBACrC;YACH,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QAC9C,CAAC,CAAC;QACF,MAAM,EAAE,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC;AA/CD,gEA+CC"}
@@ -0,0 +1,5 @@
1
+ export interface TunnelExecutorOptions {
2
+ outputPath: string;
3
+ debug: boolean;
4
+ verbose: boolean;
5
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "version": 2,
3
+ "outputCapture": "direct-nodejs",
4
+ "$schema": "http://json-schema.org/schema",
5
+ "cli": "nx",
6
+ "title": "Forge application serve target",
7
+ "description": "Forge application serve target",
8
+ "type": "object",
9
+ "properties": {
10
+ "outputPath": {
11
+ "type": "string",
12
+ "description": "The output path of the Forge app files.",
13
+ "visible": false
14
+ },
15
+ "debug": {
16
+ "type": "boolean",
17
+ "description": "Run Forge tunnel in debug mode.",
18
+ "alias": "d",
19
+ "default": false
20
+ },
21
+ "verbose": {
22
+ "type": "boolean",
23
+ "description": "Run Forge tunnel in verbose mode.",
24
+ "alias": "v",
25
+ "default": false
26
+ }
27
+ },
28
+ "required": ["outputPath"]
29
+ }
@@ -15,7 +15,15 @@ After that, proceed with the initial registration of the app with the Forge plat
15
15
 
16
16
  This will initially register the app with the Forge platform, deploy the code and finally install the app on any of your Atlassian applications.
17
17
 
18
- ## Dev loop
18
+ ## Tunnel-based dev loop
19
+
20
+ Before you tunnel a Forge app, make sure you have completed the prerequisites steps above. After that, run
21
+
22
+ nx serve <%= name %>
23
+
24
+ This will start the `serve` target for all Custom UI projects defined in the app `manifest.yml` on their specified tunnel port. After that, it will start a build process in watch mode for the Forge app itself, before ultimately, starting the `forge tunnel` process for the Forge app.
25
+
26
+ ## Manual dev loop
19
27
 
20
28
  When the app code changes, the updated code has to rebuilt by calling
21
29
 
@@ -23,12 +31,14 @@ When the app code changes, the updated code has to rebuilt by calling
23
31
 
24
32
  and re-deployed to the Forge platform using
25
33
 
26
- forge deploy
34
+ nx deploy <%= name %>
27
35
 
28
36
  If the app's `manifest.yml` changed, you may have to upgrade an existing installation by running
29
37
 
30
38
  forge install --upgrade
31
39
 
40
+ from within the dist directory.
41
+
32
42
 
33
43
 
34
44
 
@@ -4,18 +4,9 @@ exports.getServeConfig = void 0;
4
4
  const devkit_1 = require("@nrwl/devkit");
5
5
  function getServeConfig(project, options) {
6
6
  return {
7
- executor: '@nrwl/workspace:run-commands',
7
+ executor: '@toolsplus/nx-forge:tunnel',
8
8
  options: {
9
- commands: [
10
- {
11
- command: `nx run ${options.name}:build --watch`,
12
- },
13
- {
14
- command: `forge tunnel`,
15
- },
16
- ],
17
- cwd: (0, devkit_1.joinPathFragments)('dist', options.appProjectRoot),
18
- parallel: true,
9
+ outputPath: (0, devkit_1.joinPathFragments)('dist', options.appProjectRoot),
19
10
  },
20
11
  };
21
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"get-serve-config.js","sourceRoot":"","sources":["../../../../../../../packages/forge/src/generators/application/lib/get-serve-config.ts"],"names":[],"mappings":";;;AACA,yCAIsB;AAEtB,SAAgB,cAAc,CAC5B,OAA6B,EAC7B,OAA0B;IAE1B,OAAO;QACL,QAAQ,EAAE,8BAA8B;QACxC,OAAO,EAAE;YACP,QAAQ,EAAE;gBACR;oBACE,OAAO,EAAE,UAAU,OAAO,CAAC,IAAI,gBAAgB;iBAChD;gBACD;oBACE,OAAO,EAAE,cAAc;iBACxB;aACF;YACD,GAAG,EAAE,IAAA,0BAAiB,EAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC;YACtD,QAAQ,EAAE,IAAI;SACf;KACF,CAAC;AACJ,CAAC;AAnBD,wCAmBC"}
1
+ {"version":3,"file":"get-serve-config.js","sourceRoot":"","sources":["../../../../../../../packages/forge/src/generators/application/lib/get-serve-config.ts"],"names":[],"mappings":";;;AACA,yCAIsB;AAEtB,SAAgB,cAAc,CAC5B,OAA6B,EAC7B,OAA0B;IAE1B,OAAO;QACL,QAAQ,EAAE,4BAA4B;QACtC,OAAO,EAAE;YACP,UAAU,EAAE,IAAA,0BAAiB,EAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC;SAC9D;KACF,CAAC;AACJ,CAAC;AAVD,wCAUC"}
@@ -2,14 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const devkit_1 = require("@nrwl/devkit");
5
- const set_default_collection_1 = require("@nrwl/workspace/src/utilities/set-default-collection");
6
5
  const run_tasks_in_serial_1 = require("@nrwl/workspace/src/utilities/run-tasks-in-serial");
7
6
  const lib_1 = require("./lib");
8
7
  const jest_1 = require("@nrwl/jest");
9
8
  function default_1(tree, rawOptions) {
10
9
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
11
10
  const options = (0, lib_1.normalizeOptions)(rawOptions);
12
- (0, set_default_collection_1.setDefaultCollection)(tree, '@toolsplus/nx-forge');
13
11
  const jestTask = (0, jest_1.jestInitGenerator)(tree, {});
14
12
  const installPackagesTask = (0, lib_1.addDependencies)(tree);
15
13
  if (!options.skipFormat) {
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/forge/src/generators/init/generator.ts"],"names":[],"mappings":";;;AAAA,yCAAoE;AACpE,iGAA4F;AAC5F,2FAAqF;AAErF,+BAA0D;AAC1D,qCAA+C;AAE/C,mBACE,IAAU,EACV,UAA+B;;QAE/B,MAAM,OAAO,GAAG,IAAA,sBAAgB,EAAC,UAAU,CAAC,CAAC;QAC7C,IAAA,6CAAoB,EAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;QAElD,MAAM,QAAQ,GAAG,IAAA,wBAAiB,EAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7C,MAAM,mBAAmB,GAAG,IAAA,qBAAe,EAAC,IAAI,CAAC,CAAC;QAElD,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;YACvB,MAAM,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC;SACzB;QAED,OAAO,IAAA,sCAAgB,EAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;IACzD,CAAC;CAAA;AAfD,4BAeC"}
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/forge/src/generators/init/generator.ts"],"names":[],"mappings":";;;AAAA,yCAAoE;AACpE,2FAAqF;AAErF,+BAA0D;AAC1D,qCAA+C;AAE/C,mBACE,IAAU,EACV,UAA+B;;QAE/B,MAAM,OAAO,GAAG,IAAA,sBAAgB,EAAC,UAAU,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAA,wBAAiB,EAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7C,MAAM,mBAAmB,GAAG,IAAA,qBAAe,EAAC,IAAI,CAAC,CAAC;QAElD,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;YACvB,MAAM,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC;SACzB;QAED,OAAO,IAAA,sCAAgB,EAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;IACzD,CAAC;CAAA;AAbD,4BAaC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-manifest-yml.js","sourceRoot":"","sources":["../../../../../../packages/forge/src/utils/forge/load-manifest-yml.ts"],"names":[],"mappings":";;;;AAAA,8CAMyB;AACzB,+EAA+E;AAE/E,SAAsB,eAAe,CACnC,YAAoB;;QAEpB,MAAM,EACJ,cAAc,EACd,OAAO,EAAE,sBAAsB,EAC/B,MAAM,GACP,GAAG,MAAM,IAAI,oBAAoB,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAE3D,IAAI,CAAC,sBAAsB,EAAE;YAC3B,MAAM,IAAI,KAAK,CACb,iCAAiC,YAAY,MAAM,MAAM;iBACtD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;iBACrB,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAC;SACH;QAED,MAAM,cAAc,GAAmB,cAAc,CAAC,YAAY,CAAC;QAEnE,IAAI,CAAC,cAAc,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;SACtE;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;CAAA;AAxBD,0CAwBC;AAED,MAAM,oBAAqB,SAAQ,sCAA2C;IAC5E;QACE,KAAK,CAAC;YACJ,IAAI,wBAAa,EAAE;YACnB,IAAI,wBAAa,EAAE;YACnB,IAAI,0BAAe,CAAC,WAAW,CAAC;SACjC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"load-manifest-yml.js","sourceRoot":"","sources":["../../../../../../../packages/forge/src/executors/build/lib/load-manifest-yml.ts"],"names":[],"mappings":";;;;AAAA,8CAMyB;AACzB,+EAA+E;AAE/E,SAAsB,eAAe,CACnC,YAAoB;;QAEpB,MAAM,EACJ,cAAc,EACd,OAAO,EAAE,sBAAsB,EAC/B,MAAM,GACP,GAAG,MAAM,IAAI,oBAAoB,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAE3D,IAAI,CAAC,sBAAsB,EAAE;YAC3B,MAAM,IAAI,KAAK,CACb,iCAAiC,YAAY,MAAM,MAAM;iBACtD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;iBACrB,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAC;SACH;QAED,MAAM,cAAc,GAAmB,cAAc,CAAC,YAAY,CAAC;QAEnE,IAAI,CAAC,cAAc,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;SACtE;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;CAAA;AAxBD,0CAwBC;AAED,MAAM,oBAAqB,SAAQ,sCAA2C;IAC5E;QACE,KAAK,CAAC;YACJ,IAAI,wBAAa,EAAE;YACnB,IAAI,wBAAa,EAAE;YACnB,IAAI,0BAAe,CAAC,WAAW,CAAC;SACjC,CAAC,CAAC;IACL,CAAC;CACF"}