@adobe/aio-cli-plugin-api-mesh 5.2.2-beta.2 → 5.2.3-alpha
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 +7 -3
- package/src/commands/api-mesh/__tests__/create.test.js +18 -6
- package/src/commands/api-mesh/__tests__/run.test.js +191 -65
- package/src/commands/api-mesh/__tests__/update.test.js +4 -2
- package/src/commands/api-mesh/create.js +2 -3
- package/src/commands/api-mesh/run.js +207 -161
- package/src/commands/api-mesh/update.js +2 -3
- package/src/commands/{PLUGINNAME/__tests__/index.test.js → api-mesh.js} +13 -15
- package/src/helpers.js +20 -10
- package/src/lib/devConsole.js +1 -1
- package/src/meshArtifact.js +231 -0
- package/src/project.js +56 -0
- package/src/server.js +74 -32
- package/src/utils.js +10 -2
- package/src/{index.js → worker.js} +9 -7
- package/src/wranglerCli.js +54 -0
- package/src/commands/PLUGINNAME/index.js +0 -32
- package/src/wranglerServer.js +0 -80
|
@@ -17,7 +17,7 @@ jest.mock('../../../helpers', () => ({
|
|
|
17
17
|
initSdk: jest.fn().mockResolvedValue({}),
|
|
18
18
|
initRequestId: jest.fn().mockResolvedValue({}),
|
|
19
19
|
promptConfirm: jest.fn().mockResolvedValue(true),
|
|
20
|
-
importFiles: jest.fn().mockResolvedValue(),
|
|
20
|
+
importFiles: jest.fn().mockResolvedValue({}),
|
|
21
21
|
}));
|
|
22
22
|
jest.mock('@adobe/aio-cli-lib-console', () => ({
|
|
23
23
|
init: jest.fn().mockResolvedValue(mockConsoleCLIInstance),
|
|
@@ -547,7 +547,9 @@ describe('update command tests', () => {
|
|
|
547
547
|
});
|
|
548
548
|
|
|
549
549
|
importFiles.mockResolvedValueOnce({
|
|
550
|
-
|
|
550
|
+
data: {
|
|
551
|
+
meshConfig,
|
|
552
|
+
},
|
|
551
553
|
});
|
|
552
554
|
|
|
553
555
|
const output = await UpdateCommand.run();
|
|
@@ -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.');
|
|
@@ -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,
|
|
@@ -37,8 +38,15 @@ const {
|
|
|
37
38
|
const logger = require('../../classes/logger');
|
|
38
39
|
const { getMeshId, getMeshArtifact } = require('../../lib/devConsole');
|
|
39
40
|
require('dotenv').config();
|
|
40
|
-
const {
|
|
41
|
-
const {
|
|
41
|
+
const { start } = require('../../wranglerCli');
|
|
42
|
+
const {
|
|
43
|
+
resolveOriginalSources,
|
|
44
|
+
copyBuiltMeshToPackage,
|
|
45
|
+
BUILT_MESH_ARTIFACT_DIRECTORY,
|
|
46
|
+
safeDelete,
|
|
47
|
+
getBuiltMeshTenantDirectory,
|
|
48
|
+
} = require('../../project');
|
|
49
|
+
const { resolveRelativeSources } = require('../../meshArtifact');
|
|
42
50
|
|
|
43
51
|
const { validateMesh, buildMesh, compileMesh } = meshBuilder.default;
|
|
44
52
|
|
|
@@ -55,6 +63,7 @@ class RunCommand extends Command {
|
|
|
55
63
|
|
|
56
64
|
static flags = {
|
|
57
65
|
port: portNoFlag,
|
|
66
|
+
inspectPort: inspectPortNoFlag,
|
|
58
67
|
debug: debugFlag,
|
|
59
68
|
env: envFileFlag,
|
|
60
69
|
autoConfirmAction: autoConfirmActionFlag,
|
|
@@ -66,182 +75,219 @@ class RunCommand extends Command {
|
|
|
66
75
|
|
|
67
76
|
static examples = [];
|
|
68
77
|
|
|
69
|
-
|
|
70
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Validate the current working directory to ensure it is set up to run the command
|
|
80
|
+
* @returns {Promise<void>}
|
|
81
|
+
* @throws {Error} when project is not set up correctly
|
|
82
|
+
*/
|
|
83
|
+
async validateCwd() {
|
|
84
|
+
//Ensure that current directory includes package.json
|
|
85
|
+
if (!fs.existsSync(path.join(process.cwd(), 'package.json'))) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
'`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.',
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
71
91
|
|
|
72
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Handle remote mesh artifact
|
|
94
|
+
* @returns {Promise<string>} Mesh identifier
|
|
95
|
+
* @throws {Error} when failure retrieving remote mesh artifact
|
|
96
|
+
*/
|
|
97
|
+
async handleRemoteMeshArtifact() {
|
|
98
|
+
const { imsOrgCode, projectId, workspaceId, workspaceName } = await initSdk({});
|
|
73
99
|
|
|
74
|
-
|
|
75
|
-
|
|
100
|
+
// Get the mesh identifier for the workspace
|
|
101
|
+
let meshId;
|
|
102
|
+
try {
|
|
103
|
+
meshId = await getMeshId(imsOrgCode, projectId, workspaceId, workspaceName);
|
|
104
|
+
} catch (err) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
`Unable to get mesh ID. Please check the details and try again. RequestId: ${global.requestId}`,
|
|
107
|
+
);
|
|
108
|
+
}
|
|
76
109
|
|
|
77
|
-
|
|
78
|
-
|
|
110
|
+
try {
|
|
111
|
+
await getMeshArtifact(imsOrgCode, projectId, workspaceId, workspaceName, meshId);
|
|
112
|
+
} catch (err) {
|
|
113
|
+
throw new Error(
|
|
114
|
+
`Unable to retrieve mesh. Please check the details and try again. RequestId: ${global.requestId}`,
|
|
115
|
+
);
|
|
116
|
+
}
|
|
79
117
|
|
|
80
118
|
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 {
|
|
119
|
+
await setUpTenantFiles(meshId);
|
|
120
|
+
} catch (err) {
|
|
121
|
+
throw new Error('Failed to install downloaded mesh');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Resolve relative sources in built mesh for local development
|
|
125
|
+
const builtMeshTenantDir = getBuiltMeshTenantDirectory(meshId);
|
|
126
|
+
await resolveRelativeSources(builtMeshTenantDir);
|
|
127
|
+
|
|
128
|
+
this.log('Successfully downloaded mesh');
|
|
129
|
+
|
|
130
|
+
return meshId;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Handle local mesh configuration
|
|
135
|
+
* @param args {unknown} Arguments
|
|
136
|
+
* @param flags {unknown} Flags
|
|
137
|
+
* @returns {Promise<string>}
|
|
138
|
+
* @throws {Error} when failure building local mesh artifact
|
|
139
|
+
*/
|
|
140
|
+
async handleLocalMeshConfig(args, flags) {
|
|
141
|
+
if (!args.file) {
|
|
142
|
+
throw new Error('Missing file path. Run aio api-mesh run --help for more info.');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const envFilePath = await flags.env;
|
|
146
|
+
|
|
147
|
+
//Read the mesh input file
|
|
148
|
+
let inputMeshData = await readFileContents(args.file, this, 'mesh');
|
|
149
|
+
let data;
|
|
150
|
+
|
|
151
|
+
// TODO: Should we check for secrets in use when no secrets file provided?
|
|
152
|
+
if (checkPlaceholders(inputMeshData)) {
|
|
153
|
+
this.log('The provided mesh contains placeholders. Starting mesh interpolation process.');
|
|
154
|
+
data = await validateAndInterpolateMesh(inputMeshData, envFilePath, this);
|
|
155
|
+
} else {
|
|
156
|
+
try {
|
|
157
|
+
data = JSON.parse(inputMeshData);
|
|
158
|
+
} catch (err) {
|
|
159
|
+
this.log(err.message);
|
|
160
|
+
throw new Error('Input mesh file is not a valid JSON. Please check the file provided.');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
let filesList = [];
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
filesList = getFilesInMeshConfig(data, args.file);
|
|
168
|
+
} catch (err) {
|
|
169
|
+
this.log(err.message);
|
|
170
|
+
throw new Error('Input mesh config is not valid.');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// if local files are present, import them in files array in meshConfig
|
|
174
|
+
let localFileOverrides;
|
|
175
|
+
if (filesList.length) {
|
|
176
|
+
try {
|
|
177
|
+
// minification of js will not be done for run command if debugging is enabled
|
|
178
|
+
({ data, localFileOverrides } = await importFiles(
|
|
179
|
+
data,
|
|
180
|
+
filesList,
|
|
181
|
+
args.file,
|
|
182
|
+
flags.autoConfirmAction,
|
|
183
|
+
!flags.debug,
|
|
184
|
+
));
|
|
185
|
+
} catch (err) {
|
|
186
|
+
this.log(err.message);
|
|
209
187
|
throw new Error(
|
|
210
|
-
'
|
|
188
|
+
'Unable to import the files in the mesh config. Please check the file and try again.',
|
|
211
189
|
);
|
|
212
190
|
}
|
|
213
|
-
} catch (error) {
|
|
214
|
-
this.error(error.message);
|
|
215
191
|
}
|
|
192
|
+
// Empty mesh-artifact directory
|
|
193
|
+
safeDelete(BUILT_MESH_ARTIFACT_DIRECTORY);
|
|
194
|
+
|
|
195
|
+
//Generating unique mesh id
|
|
196
|
+
const meshId = 'testMesh';
|
|
197
|
+
await validateMesh(data.meshConfig);
|
|
198
|
+
await buildMesh(meshId, data.meshConfig);
|
|
199
|
+
await compileMesh(meshId);
|
|
200
|
+
|
|
201
|
+
// Resolve relative sources in built mesh for local development
|
|
202
|
+
const builtMeshTenantDir = getBuiltMeshTenantDirectory(meshId);
|
|
203
|
+
await resolveRelativeSources(builtMeshTenantDir);
|
|
204
|
+
await resolveOriginalSources(builtMeshTenantDir, localFileOverrides);
|
|
205
|
+
|
|
206
|
+
return meshId;
|
|
216
207
|
}
|
|
217
208
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
209
|
+
updateFlagsFromEnv(flags) {
|
|
210
|
+
if (process.env.PORT !== undefined) {
|
|
211
|
+
flags.port = this.parseInt(
|
|
212
|
+
process.env.PORT,
|
|
213
|
+
'PORT value in the .env file is not a valid integer',
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
if (process.env.INSPECT_PORT !== undefined) {
|
|
217
|
+
flags.inspectPort = this.parseInt(
|
|
218
|
+
process.env.INSPECT_PORT,
|
|
219
|
+
'INSPECT_PORT value in the .env file is not a valid integer',
|
|
220
|
+
);
|
|
222
221
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Parse integer from string
|
|
226
|
+
* @param value {string} String value
|
|
227
|
+
* @param errorMessage {string?} Optional error message when parsing fails
|
|
228
|
+
* @returns {number}
|
|
229
|
+
* @throws {Error} when value is not a valid integer
|
|
230
|
+
*/
|
|
231
|
+
parseInt(value, errorMessage) {
|
|
232
|
+
const int = parseInt(value);
|
|
233
|
+
if (isNaN(int) || !Number.isInteger(int)) {
|
|
234
|
+
throw new Error(errorMessage || `Value is not a valid integer`);
|
|
228
235
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
+
return int;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Handle secrets feature
|
|
241
|
+
* @param secretsFilePath {string} File path to secrets
|
|
242
|
+
* @param meshId {string} Mesh identifier
|
|
243
|
+
* @returns {Promise<void>}
|
|
244
|
+
*/
|
|
245
|
+
async handleSecretsFeature(secretsFilePath, meshId) {
|
|
246
|
+
if (secretsFilePath) {
|
|
247
|
+
try {
|
|
248
|
+
await validateSecretsFile(secretsFilePath);
|
|
249
|
+
const stringifiedSecrets = await interpolateSecrets(secretsFilePath, this);
|
|
250
|
+
await writeSecretsFile(stringifiedSecrets, meshId);
|
|
251
|
+
} catch (error) {
|
|
252
|
+
this.log(error.message);
|
|
253
|
+
this.error('Unable to import secrets. Please check the file and try again.');
|
|
254
|
+
}
|
|
236
255
|
}
|
|
256
|
+
}
|
|
237
257
|
|
|
238
|
-
|
|
258
|
+
async run() {
|
|
259
|
+
try {
|
|
260
|
+
await initRequestId();
|
|
261
|
+
logger.info(`RequestId: ${global.requestId}`);
|
|
262
|
+
|
|
263
|
+
const { args, flags } = await this.parse(RunCommand);
|
|
264
|
+
await this.validateCwd();
|
|
265
|
+
this.updateFlagsFromEnv(flags);
|
|
266
|
+
|
|
267
|
+
// Use remote or local mesh artifact
|
|
268
|
+
let meshId;
|
|
269
|
+
if (flags.select) {
|
|
270
|
+
meshId = await this.handleRemoteMeshArtifact();
|
|
271
|
+
} else {
|
|
272
|
+
meshId = await this.handleLocalMeshConfig(args, flags);
|
|
273
|
+
}
|
|
239
274
|
|
|
240
|
-
|
|
241
|
-
|
|
275
|
+
//secrets management
|
|
276
|
+
const secretsFilePath = await flags.secrets;
|
|
277
|
+
if (secretsFilePath) {
|
|
278
|
+
await this.handleSecretsFeature(secretsFilePath, meshId);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const builtMeshTenantDir = getBuiltMeshTenantDirectory(meshId);
|
|
282
|
+
await copyBuiltMeshToPackage(builtMeshTenantDir);
|
|
283
|
+
|
|
284
|
+
start(this, flags.port, flags.debug, flags.inspectPort);
|
|
285
|
+
if (flags.debug) {
|
|
286
|
+
this.log(`Debugging enabled on inspect port: ${flags.inspectPort}`);
|
|
287
|
+
}
|
|
288
|
+
} catch (error) {
|
|
289
|
+
this.error(error.message);
|
|
242
290
|
}
|
|
243
|
-
// At this time the bundle and build files must be copied out to the plugin directory
|
|
244
|
-
fs.cpSync('.mesh', `${__dirname}/../../../.mesh`, { recursive: true });
|
|
245
291
|
}
|
|
246
292
|
}
|
|
247
293
|
|
|
@@ -106,7 +106,7 @@ class UpdateCommand extends Command {
|
|
|
106
106
|
// if local files are present, import them in files array in meshConfig
|
|
107
107
|
if (filesList.length) {
|
|
108
108
|
try {
|
|
109
|
-
data = await importFiles(data, filesList, args.file, flags.autoConfirmAction);
|
|
109
|
+
({ data } = await importFiles(data, filesList, args.file, flags.autoConfirmAction));
|
|
110
110
|
} catch (err) {
|
|
111
111
|
this.log(err.message);
|
|
112
112
|
this.error('Unable to import the files in the mesh config. Check the file and try again.');
|
|
@@ -119,8 +119,7 @@ class UpdateCommand extends Command {
|
|
|
119
119
|
await validateSecretsFile(secretsFilePath);
|
|
120
120
|
const secretsData = await interpolateSecrets(secretsFilePath, this);
|
|
121
121
|
const publicKey = await getPublicEncryptionKey(imsOrgCode);
|
|
122
|
-
|
|
123
|
-
data.secrets = encryptedSecrets;
|
|
122
|
+
data.secrets = await encryptSecrets(publicKey, secretsData);
|
|
124
123
|
} catch (err) {
|
|
125
124
|
this.log(err.message);
|
|
126
125
|
this.error('Unable to import secrets. Check the file and try again.');
|
|
@@ -10,21 +10,19 @@ OF ANY KIND, either express or implied. See the License for the specific languag
|
|
|
10
10
|
governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
const
|
|
13
|
+
const { Help, Command } = require('@oclif/core');
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
/**
|
|
16
|
+
* API Mesh command. Defers to topic for help text.
|
|
17
|
+
*/
|
|
18
|
+
class ApiMeshCommand extends Command {
|
|
19
|
+
async run() {
|
|
20
|
+
const help = new Help(this.config);
|
|
21
|
+
await help.showHelp(['api-mesh', '--help']);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
18
24
|
|
|
19
|
-
|
|
20
|
-
|
|
25
|
+
ApiMeshCommand.description = 'Create, run, test, and deploy API Mesh';
|
|
26
|
+
ApiMeshCommand.args = [];
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
command = new IndexCommand([]);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
test('run', async () => {
|
|
27
|
-
command.argv = [];
|
|
28
|
-
await expect(command.run()).resolves.not.toThrowError();
|
|
29
|
-
});
|
|
30
|
-
});
|
|
28
|
+
module.exports = ApiMeshCommand;
|
package/src/helpers.js
CHANGED
|
@@ -445,7 +445,7 @@ async function initRequestId() {
|
|
|
445
445
|
* Function to run the CLI Y/N prompt to confirm the user's action
|
|
446
446
|
*
|
|
447
447
|
* @param {string} message
|
|
448
|
-
* @returns boolean
|
|
448
|
+
* @returns Promise<boolean>
|
|
449
449
|
*/
|
|
450
450
|
async function promptConfirm(message) {
|
|
451
451
|
const prompt = inquirer.createPromptModule({ output: process.stderr });
|
|
@@ -505,7 +505,6 @@ async function promptSelect(message, choices) {
|
|
|
505
505
|
* Function to run the CLI selectable list
|
|
506
506
|
*
|
|
507
507
|
* @param {string} message - prompt message
|
|
508
|
-
* @param {object[]} choices - list of options
|
|
509
508
|
* @returns {object[]} - selected options
|
|
510
509
|
*/
|
|
511
510
|
async function promptInput(message) {
|
|
@@ -524,9 +523,11 @@ async function promptInput(message) {
|
|
|
524
523
|
* Import the files in the files array in meshConfig
|
|
525
524
|
*
|
|
526
525
|
* @param data MeshConfig
|
|
527
|
-
* @param
|
|
526
|
+
* @param filesListArray List of files in meshConfig
|
|
528
527
|
* @param meshConfigName MeshConfigName
|
|
529
528
|
* @param autoConfirmActionFlag The user won't be prompted any questions, if this flag is set
|
|
529
|
+
* @param shouldMinifyJS
|
|
530
|
+
* @returns Promise<{{ data, localFileOverrides: string[] }}>
|
|
530
531
|
*/
|
|
531
532
|
async function importFiles(
|
|
532
533
|
data,
|
|
@@ -589,29 +590,38 @@ async function importFiles(
|
|
|
589
590
|
);
|
|
590
591
|
}
|
|
591
592
|
|
|
593
|
+
// Result of override resolution
|
|
594
|
+
const localFileOverrides = {};
|
|
592
595
|
for (let i = 0; i < overrideArr.length; i++) {
|
|
596
|
+
const fileName = overrideArr[i].fileName;
|
|
593
597
|
shouldOverride = await promptConfirm(
|
|
594
|
-
`Do you want to override the ${path.basename(
|
|
598
|
+
`Do you want to override the ${path.basename(fileName)} file?`,
|
|
595
599
|
);
|
|
596
600
|
|
|
597
601
|
if (shouldOverride) {
|
|
598
602
|
resultData = updateFilesArray(
|
|
599
603
|
resultData,
|
|
600
|
-
|
|
604
|
+
fileName,
|
|
601
605
|
meshConfigName,
|
|
602
606
|
overrideArr[i].index,
|
|
603
607
|
shouldMinifyJS,
|
|
604
608
|
);
|
|
609
|
+
localFileOverrides[fileName] = true;
|
|
610
|
+
} else {
|
|
611
|
+
localFileOverrides[fileName] = false;
|
|
605
612
|
}
|
|
606
613
|
}
|
|
607
614
|
|
|
608
|
-
return
|
|
615
|
+
return {
|
|
616
|
+
data: resultData,
|
|
617
|
+
localFileOverrides,
|
|
618
|
+
};
|
|
609
619
|
}
|
|
610
620
|
|
|
611
621
|
/**loads the pupa module dynamically and then interpolates the raw data from mesh file with object data
|
|
612
|
-
* @param
|
|
613
|
-
* @param
|
|
614
|
-
* @returns {object}
|
|
622
|
+
* @param data
|
|
623
|
+
* @param obj
|
|
624
|
+
* @returns {object}
|
|
615
625
|
*/
|
|
616
626
|
|
|
617
627
|
async function interpolateMesh(data, obj) {
|
|
@@ -845,7 +855,7 @@ async function processFileConfig(config) {
|
|
|
845
855
|
* This function sets up the tenantFiles used in a particular mesh config
|
|
846
856
|
* into the tenantFiles folder
|
|
847
857
|
*
|
|
848
|
-
* @param
|
|
858
|
+
* @param meshId
|
|
849
859
|
*/
|
|
850
860
|
async function setUpTenantFiles(meshId) {
|
|
851
861
|
if (fs.existsSync(path.resolve(process.cwd(), 'mesh-artifact', meshId, 'files.json'))) {
|
package/src/lib/devConsole.js
CHANGED
|
@@ -1064,7 +1064,7 @@ const getMeshDeployments = async (organizationCode, projectId, workspaceId, mesh
|
|
|
1064
1064
|
* As a result, we provide the publicKey used for secrets encryption.
|
|
1065
1065
|
* The near-term goal is to stop using Dev Console as a proxy for all routes.
|
|
1066
1066
|
* @param organizationCode
|
|
1067
|
-
* @returns string
|
|
1067
|
+
* @returns Promise<string>
|
|
1068
1068
|
*/
|
|
1069
1069
|
const getPublicEncryptionKey = async organizationCode => {
|
|
1070
1070
|
const { accessToken } = await getDevConsoleConfig();
|