@adobe/aio-cli-plugin-api-mesh 5.2.4-alpha.0 → 5.3.0-beta.1
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/oclif.manifest.json +1 -1
- package/package.json +13 -6
- package/src/commands/api-mesh/__tests__/cache-purge.test.js +1 -2
- package/src/commands/api-mesh/__tests__/create.test.js +19 -22
- package/src/commands/api-mesh/__tests__/delete-log-forwarding.test.js +106 -0
- package/src/commands/api-mesh/__tests__/delete.test.js +1 -2
- package/src/commands/api-mesh/__tests__/describe.test.js +1 -3
- package/src/commands/api-mesh/__tests__/get.test.js +2 -2
- package/src/commands/api-mesh/__tests__/log-get-bulk.test.js +19 -213
- package/src/commands/api-mesh/__tests__/run.test.js +191 -65
- package/src/commands/api-mesh/__tests__/update.test.js +8 -7
- package/src/commands/api-mesh/cache/purge.js +1 -3
- package/src/commands/api-mesh/config/delete/log-forwarding.js +80 -0
- package/src/commands/api-mesh/create.js +22 -6
- package/src/commands/api-mesh/delete.js +1 -3
- package/src/commands/api-mesh/describe.js +1 -3
- package/src/commands/api-mesh/get.js +1 -3
- package/src/commands/api-mesh/log-get-bulk.js +5 -26
- package/src/commands/api-mesh/log-get.js +1 -3
- package/src/commands/api-mesh/log-list.js +1 -3
- package/src/commands/api-mesh/run.js +207 -168
- package/src/commands/api-mesh/source/discover.js +2 -9
- package/src/commands/api-mesh/source/get.js +1 -8
- package/src/commands/api-mesh/source/install.js +1 -2
- package/src/commands/api-mesh/status.js +1 -2
- package/src/commands/api-mesh/update.js +21 -6
- package/src/commands/{PLUGINNAME/__tests__/index.test.js → api-mesh.js} +13 -15
- package/src/helpers.js +73 -15
- package/src/hooks/initMetadata.js +8 -0
- package/src/lib/smsClient.js +115 -1
- package/src/meshArtifact.js +231 -0
- package/src/project.js +56 -0
- package/src/server.js +74 -32
- package/src/utils.js +26 -24
- package/src/{index.js → worker.js} +9 -7
- package/src/wranglerCli.js +54 -0
- package/wrangler.toml +13 -0
- package/src/commands/PLUGINNAME/index.js +0 -32
- package/src/wranglerServer.js +0 -80
|
@@ -10,7 +10,9 @@ governing permissions and limitations under the License.
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
const { Command } = require('@oclif/core');
|
|
13
|
-
const
|
|
13
|
+
const chalk = require('chalk');
|
|
14
|
+
|
|
15
|
+
const { initSdk, promptConfirm, importFiles } = require('../../helpers');
|
|
14
16
|
const logger = require('../../classes/logger');
|
|
15
17
|
const {
|
|
16
18
|
ignoreCacheFlag,
|
|
@@ -42,8 +44,6 @@ class CreateCommand extends Command {
|
|
|
42
44
|
static enableJsonFlag = true;
|
|
43
45
|
|
|
44
46
|
async run() {
|
|
45
|
-
await initRequestId();
|
|
46
|
-
|
|
47
47
|
logger.info(`RequestId: ${global.requestId}`);
|
|
48
48
|
|
|
49
49
|
const { args, flags } = await this.parse(CreateCommand);
|
|
@@ -99,7 +99,7 @@ class CreateCommand extends Command {
|
|
|
99
99
|
// if local files are present, import them in files array in meshConfig
|
|
100
100
|
if (filesList.length) {
|
|
101
101
|
try {
|
|
102
|
-
data = await importFiles(data, filesList, args.file, flags.autoConfirmAction);
|
|
102
|
+
({ data } = await importFiles(data, filesList, args.file, flags.autoConfirmAction));
|
|
103
103
|
} catch (err) {
|
|
104
104
|
this.log(err.message);
|
|
105
105
|
this.error('Unable to import the files in the mesh config. Check the file and try again.');
|
|
@@ -112,8 +112,7 @@ class CreateCommand extends Command {
|
|
|
112
112
|
await validateSecretsFile(secretsFilePath);
|
|
113
113
|
const secretsData = await interpolateSecrets(secretsFilePath, this);
|
|
114
114
|
const publicKey = await getPublicEncryptionKey(imsOrgCode);
|
|
115
|
-
|
|
116
|
-
data.secrets = encryptedSecrets;
|
|
115
|
+
data.secrets = await encryptSecrets(publicKey, secretsData);
|
|
117
116
|
} catch (err) {
|
|
118
117
|
this.log(err.message);
|
|
119
118
|
this.error('Unable to import secrets. Check the file and try again.');
|
|
@@ -122,6 +121,23 @@ class CreateCommand extends Command {
|
|
|
122
121
|
|
|
123
122
|
let shouldContinue = true;
|
|
124
123
|
|
|
124
|
+
if (
|
|
125
|
+
data?.meshConfig?.responseConfig?.includeHTTPDetails &&
|
|
126
|
+
workspaceName.toLowerCase() === 'production'
|
|
127
|
+
) {
|
|
128
|
+
this.warn(
|
|
129
|
+
`Your mesh has ${chalk.yellowBright('includeHTTPDetails')} set to ${chalk.redBright(
|
|
130
|
+
'true',
|
|
131
|
+
)}. This is a security risk and should not be used in production.\n` +
|
|
132
|
+
`When ${chalk.yellowBright('includeHTTPDetails')} is set to ${chalk.redBright(
|
|
133
|
+
'true',
|
|
134
|
+
)} it exposes HTTP request and response details in the mesh logs, which can cause sensitive information to be exposed.\n` +
|
|
135
|
+
`Consider setting ${chalk.yellowBright('includeHTTPDetails')} to ${chalk.greenBright(
|
|
136
|
+
'false',
|
|
137
|
+
)} in your mesh configuration file.`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
125
141
|
if (!autoConfirmAction) {
|
|
126
142
|
shouldContinue = await promptConfirm(`Are you sure you want to create a mesh?`);
|
|
127
143
|
}
|
|
@@ -12,7 +12,7 @@ governing permissions and limitations under the License.
|
|
|
12
12
|
const { Command } = require('@oclif/command');
|
|
13
13
|
|
|
14
14
|
const logger = require('../../classes/logger');
|
|
15
|
-
const { initSdk,
|
|
15
|
+
const { initSdk, promptConfirm } = require('../../helpers');
|
|
16
16
|
const { ignoreCacheFlag, autoConfirmActionFlag } = require('../../utils');
|
|
17
17
|
const { getMeshId, deleteMesh } = require('../../lib/smsClient');
|
|
18
18
|
|
|
@@ -25,8 +25,6 @@ class DeleteCommand extends Command {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
async run() {
|
|
28
|
-
await initRequestId();
|
|
29
|
-
|
|
30
28
|
logger.info(`RequestId: ${global.requestId}`);
|
|
31
29
|
|
|
32
30
|
const { flags } = await this.parse(DeleteCommand);
|
|
@@ -11,7 +11,7 @@ governing permissions and limitations under the License.
|
|
|
11
11
|
|
|
12
12
|
const { Command } = require('@oclif/command');
|
|
13
13
|
const logger = require('../../classes/logger');
|
|
14
|
-
const { initSdk
|
|
14
|
+
const { initSdk } = require('../../helpers');
|
|
15
15
|
const { ignoreCacheFlag } = require('../../utils');
|
|
16
16
|
const { describeMesh } = require('../../lib/smsClient');
|
|
17
17
|
const { buildMeshUrl } = require('../../urlBuilder');
|
|
@@ -24,8 +24,6 @@ class DescribeCommand extends Command {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
async run() {
|
|
27
|
-
await initRequestId();
|
|
28
|
-
|
|
29
27
|
logger.info(`RequestId: ${global.requestId}`);
|
|
30
28
|
|
|
31
29
|
const { flags } = await this.parse(DescribeCommand);
|
|
@@ -13,7 +13,7 @@ const { Command } = require('@oclif/core');
|
|
|
13
13
|
const { writeFile } = require('fs/promises');
|
|
14
14
|
|
|
15
15
|
const logger = require('../../classes/logger');
|
|
16
|
-
const { initSdk
|
|
16
|
+
const { initSdk } = require('../../helpers');
|
|
17
17
|
const { ignoreCacheFlag, jsonFlag } = require('../../utils');
|
|
18
18
|
const { getMeshId, getMesh } = require('../../lib/smsClient');
|
|
19
19
|
const { buildMeshUrl } = require('../../urlBuilder');
|
|
@@ -29,8 +29,6 @@ class GetCommand extends Command {
|
|
|
29
29
|
static enableJsonFlag = true;
|
|
30
30
|
|
|
31
31
|
async run() {
|
|
32
|
-
await initRequestId();
|
|
33
|
-
|
|
34
32
|
logger.info(`RequestId: ${global.requestId}`);
|
|
35
33
|
|
|
36
34
|
const { args, flags } = await this.parse(GetCommand);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { Command } = require('@oclif/core');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
|
-
const {
|
|
4
|
+
const { initSdk, promptConfirm } = require('../../helpers');
|
|
5
5
|
const { getMeshId, getPresignedUrls } = require('../../lib/smsClient');
|
|
6
6
|
const logger = require('../../classes/logger');
|
|
7
7
|
const axios = require('axios');
|
|
@@ -11,12 +11,10 @@ const {
|
|
|
11
11
|
endTimeFlag,
|
|
12
12
|
logFilenameFlag,
|
|
13
13
|
pastFlag,
|
|
14
|
-
fromFlag,
|
|
15
14
|
suggestCorrectedDateFormat,
|
|
16
15
|
parsePastDuration,
|
|
17
16
|
validateDateTimeRange,
|
|
18
17
|
validateDateTimeFormat,
|
|
19
|
-
localToUTCTime,
|
|
20
18
|
} = require('../../utils');
|
|
21
19
|
|
|
22
20
|
require('dotenv').config();
|
|
@@ -28,7 +26,6 @@ class GetBulkLogCommand extends Command {
|
|
|
28
26
|
endTime: endTimeFlag,
|
|
29
27
|
filename: logFilenameFlag,
|
|
30
28
|
past: pastFlag,
|
|
31
|
-
from: fromFlag,
|
|
32
29
|
};
|
|
33
30
|
|
|
34
31
|
async run() {
|
|
@@ -36,7 +33,6 @@ class GetBulkLogCommand extends Command {
|
|
|
36
33
|
const columnHeaders =
|
|
37
34
|
'EventTimestampMs,Exceptions,Logs,Outcome,MeshId,RayID,URL,Request Method,Response Status,Level';
|
|
38
35
|
|
|
39
|
-
await initRequestId();
|
|
40
36
|
logger.info(`RequestId: ${global.requestId}`);
|
|
41
37
|
const { flags } = await this.parse(GetBulkLogCommand);
|
|
42
38
|
const ignoreCache = await flags.ignoreCache;
|
|
@@ -90,26 +86,9 @@ class GetBulkLogCommand extends Command {
|
|
|
90
86
|
formattedEndTime = flags.endTime.replace(/-|:|Z/g, '').replace('T', 'T');
|
|
91
87
|
} else if (flags.past) {
|
|
92
88
|
const pastTimeWindow = parsePastDuration(flags.past);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (!dateTimeRegex.test(flags.from)) {
|
|
97
|
-
this.error('Invalid format. Use the format YYYY-MM-DD:HH:MM:SS for --from.');
|
|
98
|
-
} else {
|
|
99
|
-
try {
|
|
100
|
-
convertedTime = await localToUTCTime(flags.from.toString());
|
|
101
|
-
} catch (error) {
|
|
102
|
-
this.error(`Invalid date components passed in --from. Correct the date.`);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
// add the past window to the converted time to get the end time to fetch logs from the past
|
|
106
|
-
calculatedStartTime = new Date(convertedTime);
|
|
107
|
-
calculatedEndTime = new Date(calculatedStartTime.getTime() + pastTimeWindow);
|
|
108
|
-
} else {
|
|
109
|
-
// subtract the past window from the current time to get the start time to fetch recent logs from now
|
|
110
|
-
calculatedEndTime = new Date();
|
|
111
|
-
calculatedStartTime = new Date(calculatedEndTime.getTime() - pastTimeWindow);
|
|
112
|
-
}
|
|
89
|
+
// Subtract the past window from the current time to get the start time to fetch recent logs from now
|
|
90
|
+
calculatedEndTime = new Date();
|
|
91
|
+
calculatedStartTime = new Date(calculatedEndTime.getTime() - pastTimeWindow);
|
|
113
92
|
|
|
114
93
|
// Validate the calculated start and end times range
|
|
115
94
|
validateDateTimeRange(calculatedStartTime, calculatedEndTime);
|
|
@@ -121,7 +100,7 @@ class GetBulkLogCommand extends Command {
|
|
|
121
100
|
return;
|
|
122
101
|
} else {
|
|
123
102
|
this.error(
|
|
124
|
-
'Missing required flags. Provide
|
|
103
|
+
'Missing required flags. Provide a time range with --startTime and --endTime flags, or use the --past flag for more recent logs. Use the `mesh log:get-bulk --help` command for more information.',
|
|
125
104
|
);
|
|
126
105
|
return;
|
|
127
106
|
}
|
|
@@ -10,7 +10,7 @@ governing permissions and limitations under the License.
|
|
|
10
10
|
*/
|
|
11
11
|
const { Command } = require('@oclif/core');
|
|
12
12
|
const logger = require('../../classes/logger');
|
|
13
|
-
const { initSdk
|
|
13
|
+
const { initSdk } = require('../../helpers');
|
|
14
14
|
const { ignoreCacheFlag } = require('../../utils');
|
|
15
15
|
const { getMeshId, getLogsByRayId } = require('../../lib/smsClient');
|
|
16
16
|
require('dotenv').config();
|
|
@@ -22,8 +22,6 @@ class FetchLogsCommand extends Command {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
async run() {
|
|
25
|
-
await initRequestId();
|
|
26
|
-
|
|
27
25
|
logger.info(`RequestId: ${global.requestId}`);
|
|
28
26
|
|
|
29
27
|
const { args, flags } = await this.parse(FetchLogsCommand);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { Command } = require('@oclif/core');
|
|
2
2
|
|
|
3
3
|
const logger = require('../../classes/logger');
|
|
4
|
-
const { initSdk
|
|
4
|
+
const { initSdk } = require('../../helpers');
|
|
5
5
|
const { ignoreCacheFlag, fileNameFlag } = require('../../utils');
|
|
6
6
|
const { getMeshId, listLogs } = require('../../lib/smsClient');
|
|
7
7
|
const { appendFileSync, existsSync } = require('fs');
|
|
@@ -18,8 +18,6 @@ class ListLogsCommand extends Command {
|
|
|
18
18
|
static enableJsonFlag = true;
|
|
19
19
|
|
|
20
20
|
async run() {
|
|
21
|
-
await initRequestId();
|
|
22
|
-
|
|
23
21
|
logger.info(`RequestId: ${global.requestId}`);
|
|
24
22
|
|
|
25
23
|
const { flags } = await this.parse(ListLogsCommand);
|
|
@@ -13,6 +13,7 @@ const { Command } = require('@oclif/core');
|
|
|
13
13
|
const {
|
|
14
14
|
portNoFlag,
|
|
15
15
|
debugFlag,
|
|
16
|
+
inspectPortNoFlag,
|
|
16
17
|
selectFlag,
|
|
17
18
|
envFileFlag,
|
|
18
19
|
secretsFlag,
|
|
@@ -27,18 +28,19 @@ const {
|
|
|
27
28
|
const meshBuilder = require('@adobe-apimesh/mesh-builder');
|
|
28
29
|
const fs = require('fs');
|
|
29
30
|
const path = require('path');
|
|
30
|
-
const {
|
|
31
|
-
initSdk,
|
|
32
|
-
initRequestId,
|
|
33
|
-
importFiles,
|
|
34
|
-
setUpTenantFiles,
|
|
35
|
-
writeSecretsFile,
|
|
36
|
-
} = require('../../helpers');
|
|
31
|
+
const { initSdk, importFiles, setUpTenantFiles, writeSecretsFile } = require('../../helpers');
|
|
37
32
|
const logger = require('../../classes/logger');
|
|
38
33
|
const { getMeshId, getMeshArtifact } = require('../../lib/smsClient');
|
|
39
34
|
require('dotenv').config();
|
|
40
|
-
const {
|
|
41
|
-
const {
|
|
35
|
+
const { start } = require('../../wranglerCli');
|
|
36
|
+
const {
|
|
37
|
+
resolveOriginalSources,
|
|
38
|
+
copyBuiltMeshToPackage,
|
|
39
|
+
BUILT_MESH_ARTIFACT_DIRECTORY,
|
|
40
|
+
safeDelete,
|
|
41
|
+
getBuiltMeshTenantDirectory,
|
|
42
|
+
} = require('../../project');
|
|
43
|
+
const { resolveRelativeSources } = require('../../meshArtifact');
|
|
42
44
|
|
|
43
45
|
const { validateMesh, buildMesh, compileMesh } = meshBuilder.default;
|
|
44
46
|
|
|
@@ -55,6 +57,7 @@ class RunCommand extends Command {
|
|
|
55
57
|
|
|
56
58
|
static flags = {
|
|
57
59
|
port: portNoFlag,
|
|
60
|
+
inspectPort: inspectPortNoFlag,
|
|
58
61
|
debug: debugFlag,
|
|
59
62
|
env: envFileFlag,
|
|
60
63
|
autoConfirmAction: autoConfirmActionFlag,
|
|
@@ -66,182 +69,218 @@ class RunCommand extends Command {
|
|
|
66
69
|
|
|
67
70
|
static examples = [];
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Validate the current working directory to ensure it is set up to run the command
|
|
74
|
+
* @returns {Promise<void>}
|
|
75
|
+
* @throws {Error} when project is not set up correctly
|
|
76
|
+
*/
|
|
77
|
+
async validateCwd() {
|
|
78
|
+
//Ensure that current directory includes package.json
|
|
79
|
+
if (!fs.existsSync(path.join(process.cwd(), 'package.json'))) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
'`aio api-mesh run` cannot be executed because there is no package.json file in the current directory. Use `aio api-mesh init` to set up a package.',
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
71
85
|
|
|
72
|
-
|
|
86
|
+
/**
|
|
87
|
+
* Handle remote mesh artifact
|
|
88
|
+
* @returns {Promise<string>} Mesh identifier
|
|
89
|
+
* @throws {Error} when failure retrieving remote mesh artifact
|
|
90
|
+
*/
|
|
91
|
+
async handleRemoteMeshArtifact() {
|
|
92
|
+
const { imsOrgCode, projectId, workspaceId, workspaceName } = await initSdk({});
|
|
73
93
|
|
|
74
|
-
|
|
75
|
-
|
|
94
|
+
// Get the mesh identifier for the workspace
|
|
95
|
+
let meshId;
|
|
96
|
+
try {
|
|
97
|
+
meshId = await getMeshId(imsOrgCode, projectId, workspaceId, workspaceName);
|
|
98
|
+
} catch (err) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`Unable to get mesh ID. Please check the details and try again. RequestId: ${global.requestId}`,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
76
103
|
|
|
77
|
-
|
|
78
|
-
|
|
104
|
+
try {
|
|
105
|
+
await getMeshArtifact(imsOrgCode, projectId, workspaceId, workspaceName, meshId);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`Unable to retrieve mesh. Please check the details and try again. RequestId: ${global.requestId}`,
|
|
109
|
+
);
|
|
110
|
+
}
|
|
79
111
|
|
|
80
112
|
try {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
// minification of js will not be done for run command if debugging is enabled
|
|
150
|
-
data = await importFiles(
|
|
151
|
-
data,
|
|
152
|
-
filesList,
|
|
153
|
-
args.file,
|
|
154
|
-
flags.autoConfirmAction,
|
|
155
|
-
!flags.debug,
|
|
156
|
-
);
|
|
157
|
-
} catch (err) {
|
|
158
|
-
this.log(err.message);
|
|
159
|
-
throw new Error(
|
|
160
|
-
'Unable to import the files in the mesh config. Please check the file and try again.',
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
//Generating unique mesh id
|
|
166
|
-
meshId = 'testMesh';
|
|
167
|
-
|
|
168
|
-
await validateMesh(data.meshConfig);
|
|
169
|
-
await buildMesh(meshId, data.meshConfig);
|
|
170
|
-
await compileMesh(meshId);
|
|
171
|
-
}
|
|
172
|
-
let portNo;
|
|
173
|
-
//secrets management
|
|
174
|
-
if (secretsFilePath) {
|
|
175
|
-
try {
|
|
176
|
-
await validateSecretsFile(secretsFilePath);
|
|
177
|
-
const stringifiedSecrets = await interpolateSecrets(secretsFilePath, this);
|
|
178
|
-
await writeSecretsFile(stringifiedSecrets, meshId);
|
|
179
|
-
} catch (error) {
|
|
180
|
-
this.log(error.message);
|
|
181
|
-
this.error('Unable to import secrets. Please check the file and try again.');
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
await this.copyMeshContent(meshId);
|
|
186
|
-
|
|
187
|
-
//To set the port number using the environment file
|
|
188
|
-
if (process.env.PORT !== undefined) {
|
|
189
|
-
if (isNaN(process.env.PORT) || !Number.isInteger(parseInt(process.env.PORT))) {
|
|
190
|
-
throw new Error('PORT value in the .env file is not a valid integer');
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
portNo = process.env.PORT;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
//To set the port number as the provided value in the command
|
|
197
|
-
if (flags.port !== undefined) {
|
|
198
|
-
portNo = flags.port;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
//To set the default port to 5000
|
|
202
|
-
if (!portNo) {
|
|
203
|
-
portNo = 5000;
|
|
204
|
-
}
|
|
205
|
-
this.log(`Starting server on port : ${portNo}`);
|
|
206
|
-
await runServer(portNo);
|
|
207
|
-
this.log(`Server is running on http://localhost:${portNo}/graphql`);
|
|
208
|
-
} else {
|
|
113
|
+
await setUpTenantFiles(meshId);
|
|
114
|
+
} catch (err) {
|
|
115
|
+
throw new Error('Failed to install downloaded mesh');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Resolve relative sources in built mesh for local development
|
|
119
|
+
const builtMeshTenantDir = getBuiltMeshTenantDirectory(meshId);
|
|
120
|
+
await resolveRelativeSources(builtMeshTenantDir);
|
|
121
|
+
|
|
122
|
+
this.log('Successfully downloaded mesh');
|
|
123
|
+
|
|
124
|
+
return meshId;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Handle local mesh configuration
|
|
129
|
+
* @param args {unknown} Arguments
|
|
130
|
+
* @param flags {unknown} Flags
|
|
131
|
+
* @returns {Promise<string>}
|
|
132
|
+
* @throws {Error} when failure building local mesh artifact
|
|
133
|
+
*/
|
|
134
|
+
async handleLocalMeshConfig(args, flags) {
|
|
135
|
+
if (!args.file) {
|
|
136
|
+
throw new Error('Missing file path. Run aio api-mesh run --help for more info.');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const envFilePath = await flags.env;
|
|
140
|
+
|
|
141
|
+
//Read the mesh input file
|
|
142
|
+
let inputMeshData = await readFileContents(args.file, this, 'mesh');
|
|
143
|
+
let data;
|
|
144
|
+
|
|
145
|
+
// TODO: Should we check for secrets in use when no secrets file provided?
|
|
146
|
+
if (checkPlaceholders(inputMeshData)) {
|
|
147
|
+
this.log('The provided mesh contains placeholders. Starting mesh interpolation process.');
|
|
148
|
+
data = await validateAndInterpolateMesh(inputMeshData, envFilePath, this);
|
|
149
|
+
} else {
|
|
150
|
+
try {
|
|
151
|
+
data = JSON.parse(inputMeshData);
|
|
152
|
+
} catch (err) {
|
|
153
|
+
this.log(err.message);
|
|
154
|
+
throw new Error('Input mesh file is not a valid JSON. Please check the file provided.');
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
let filesList = [];
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
filesList = getFilesInMeshConfig(data, args.file);
|
|
162
|
+
} catch (err) {
|
|
163
|
+
this.log(err.message);
|
|
164
|
+
throw new Error('Input mesh config is not valid.');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// if local files are present, import them in files array in meshConfig
|
|
168
|
+
let localFileOverrides;
|
|
169
|
+
if (filesList.length) {
|
|
170
|
+
try {
|
|
171
|
+
// minification of js will not be done for run command if debugging is enabled
|
|
172
|
+
({ data, localFileOverrides } = await importFiles(
|
|
173
|
+
data,
|
|
174
|
+
filesList,
|
|
175
|
+
args.file,
|
|
176
|
+
flags.autoConfirmAction,
|
|
177
|
+
!flags.debug,
|
|
178
|
+
));
|
|
179
|
+
} catch (err) {
|
|
180
|
+
this.log(err.message);
|
|
209
181
|
throw new Error(
|
|
210
|
-
'
|
|
182
|
+
'Unable to import the files in the mesh config. Please check the file and try again.',
|
|
211
183
|
);
|
|
212
184
|
}
|
|
213
|
-
} catch (error) {
|
|
214
|
-
this.error(error.message);
|
|
215
185
|
}
|
|
186
|
+
// Empty mesh-artifact directory
|
|
187
|
+
safeDelete(BUILT_MESH_ARTIFACT_DIRECTORY);
|
|
188
|
+
|
|
189
|
+
//Generating unique mesh id
|
|
190
|
+
const meshId = 'testMesh';
|
|
191
|
+
await validateMesh(data.meshConfig);
|
|
192
|
+
await buildMesh(meshId, data.meshConfig);
|
|
193
|
+
await compileMesh(meshId);
|
|
194
|
+
|
|
195
|
+
// Resolve relative sources in built mesh for local development
|
|
196
|
+
const builtMeshTenantDir = getBuiltMeshTenantDirectory(meshId);
|
|
197
|
+
await resolveRelativeSources(builtMeshTenantDir);
|
|
198
|
+
await resolveOriginalSources(builtMeshTenantDir, localFileOverrides);
|
|
199
|
+
|
|
200
|
+
return meshId;
|
|
216
201
|
}
|
|
217
202
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
203
|
+
updateFlagsFromEnv(flags) {
|
|
204
|
+
if (process.env.PORT !== undefined) {
|
|
205
|
+
flags.port = this.parseInt(
|
|
206
|
+
process.env.PORT,
|
|
207
|
+
'PORT value in the .env file is not a valid integer',
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
if (process.env.INSPECT_PORT !== undefined) {
|
|
211
|
+
flags.inspectPort = this.parseInt(
|
|
212
|
+
process.env.INSPECT_PORT,
|
|
213
|
+
'INSPECT_PORT value in the .env file is not a valid integer',
|
|
214
|
+
);
|
|
222
215
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Parse integer from string
|
|
220
|
+
* @param value {string} String value
|
|
221
|
+
* @param errorMessage {string?} Optional error message when parsing fails
|
|
222
|
+
* @returns {number}
|
|
223
|
+
* @throws {Error} when value is not a valid integer
|
|
224
|
+
*/
|
|
225
|
+
parseInt(value, errorMessage) {
|
|
226
|
+
const int = parseInt(value);
|
|
227
|
+
if (isNaN(int) || !Number.isInteger(int)) {
|
|
228
|
+
throw new Error(errorMessage || `Value is not a valid integer`);
|
|
228
229
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
230
|
+
return int;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Handle secrets feature
|
|
235
|
+
* @param secretsFilePath {string} File path to secrets
|
|
236
|
+
* @param meshId {string} Mesh identifier
|
|
237
|
+
* @returns {Promise<void>}
|
|
238
|
+
*/
|
|
239
|
+
async handleSecretsFeature(secretsFilePath, meshId) {
|
|
240
|
+
if (secretsFilePath) {
|
|
241
|
+
try {
|
|
242
|
+
await validateSecretsFile(secretsFilePath);
|
|
243
|
+
const stringifiedSecrets = await interpolateSecrets(secretsFilePath, this);
|
|
244
|
+
await writeSecretsFile(stringifiedSecrets, meshId);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
this.log(error.message);
|
|
247
|
+
this.error('Unable to import secrets. Please check the file and try again.');
|
|
248
|
+
}
|
|
234
249
|
}
|
|
250
|
+
}
|
|
235
251
|
|
|
236
|
-
|
|
252
|
+
async run() {
|
|
253
|
+
try {
|
|
254
|
+
logger.info(`RequestId: ${global.requestId}`);
|
|
255
|
+
|
|
256
|
+
const { args, flags } = await this.parse(RunCommand);
|
|
257
|
+
await this.validateCwd();
|
|
258
|
+
this.updateFlagsFromEnv(flags);
|
|
259
|
+
|
|
260
|
+
// Use remote or local mesh artifact
|
|
261
|
+
let meshId;
|
|
262
|
+
if (flags.select) {
|
|
263
|
+
meshId = await this.handleRemoteMeshArtifact();
|
|
264
|
+
} else {
|
|
265
|
+
meshId = await this.handleLocalMeshConfig(args, flags);
|
|
266
|
+
}
|
|
237
267
|
|
|
238
|
-
|
|
239
|
-
|
|
268
|
+
//secrets management
|
|
269
|
+
const secretsFilePath = await flags.secrets;
|
|
270
|
+
if (secretsFilePath) {
|
|
271
|
+
await this.handleSecretsFeature(secretsFilePath, meshId);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const builtMeshTenantDir = getBuiltMeshTenantDirectory(meshId);
|
|
275
|
+
await copyBuiltMeshToPackage(builtMeshTenantDir);
|
|
276
|
+
|
|
277
|
+
start(this, flags.port, flags.debug, flags.inspectPort);
|
|
278
|
+
if (flags.debug) {
|
|
279
|
+
this.log(`Debugging enabled on inspect port: ${flags.inspectPort}`);
|
|
280
|
+
}
|
|
281
|
+
} catch (error) {
|
|
282
|
+
this.error(error.message);
|
|
240
283
|
}
|
|
241
|
-
// At this time the bundle and build files must be copied out to the plugin directory
|
|
242
|
-
fs.cpSync('.mesh', `${__dirname}/../../../.mesh`, { recursive: true });
|
|
243
|
-
// Tenant files used at build time
|
|
244
|
-
fs.cpSync('tenantFiles', `${__dirname}/../../../tenantFiles`, { recursive: true });
|
|
245
284
|
}
|
|
246
285
|
}
|
|
247
286
|
|