@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.
- package/README.md +8 -0
- package/executors.json +6 -0
- package/package.json +4 -4
- package/src/executors/build/lib/patch-manifest-yml.js +1 -1
- package/src/executors/build/lib/patch-manifest-yml.js.map +1 -1
- package/src/executors/build/lib/process-custom-ui-dependencies.js +4 -3
- package/src/executors/build/lib/process-custom-ui-dependencies.js.map +1 -1
- package/src/executors/deploy/executor.js +14 -17
- package/src/executors/deploy/executor.js.map +1 -1
- package/src/executors/tunnel/executor.d.ts +14 -0
- package/src/executors/tunnel/executor.js +67 -0
- package/src/executors/tunnel/executor.js.map +1 -0
- package/src/executors/tunnel/lib/extract-custom-ui-projects.d.ts +11 -0
- package/src/executors/tunnel/lib/extract-custom-ui-projects.js +63 -0
- package/src/executors/tunnel/lib/extract-custom-ui-projects.js.map +1 -0
- package/src/executors/tunnel/lib/run-tunnel.d.ts +21 -0
- package/src/executors/tunnel/lib/run-tunnel.js +59 -0
- package/src/executors/tunnel/lib/run-tunnel.js.map +1 -0
- package/src/executors/tunnel/lib/wait-until-server-is-listening.d.ts +8 -0
- package/src/executors/tunnel/lib/wait-until-server-is-listening.js +52 -0
- package/src/executors/tunnel/lib/wait-until-server-is-listening.js.map +1 -0
- package/src/executors/tunnel/schema.d.ts +5 -0
- package/src/executors/tunnel/schema.json +29 -0
- package/src/generators/application/files/README.md +12 -2
- package/src/generators/application/lib/get-serve-config.js +2 -11
- package/src/generators/application/lib/get-serve-config.js.map +1 -1
- package/src/generators/init/generator.js +0 -2
- package/src/generators/init/generator.js.map +1 -1
- package/src/{executors/build/lib → utils/forge}/load-manifest-yml.d.ts +0 -0
- package/src/{executors/build/lib → utils/forge}/load-manifest-yml.js +0 -0
- package/src/utils/forge/load-manifest-yml.js.map +1 -0
- 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
|
+
"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.
|
|
10
|
-
"@nrwl/workspace": "^15.
|
|
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.
|
|
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("
|
|
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,
|
|
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("
|
|
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
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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,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
|
-
##
|
|
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
|
-
|
|
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: '@
|
|
7
|
+
executor: '@toolsplus/nx-forge:tunnel',
|
|
8
8
|
options: {
|
|
9
|
-
|
|
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,
|
|
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,
|
|
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"}
|
|
File without changes
|
|
File without changes
|
|
@@ -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"}
|