@adobe/aio-cli-plugin-api-mesh 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/oclif.manifest.json +1 -1
  2. package/package.json +2 -1
  3. package/src/commands/__fixtures__/files/requestParams.json +3 -0
  4. package/src/commands/__fixtures__/openapi-schema.json +4 -0
  5. package/src/commands/__fixtures__/requestParams.json +3 -0
  6. package/src/commands/__fixtures__/sample_fully_qualified_mesh.json +29 -0
  7. package/src/commands/__fixtures__/sample_invalid_mesh.txt +17 -0
  8. package/src/commands/__fixtures__/sample_mesh_files.json +23 -0
  9. package/src/commands/__fixtures__/sample_mesh_invalid_file_content.json +14 -0
  10. package/src/commands/__fixtures__/sample_mesh_invalid_file_name.json +27 -0
  11. package/src/commands/__fixtures__/sample_mesh_invalid_paths.json +23 -0
  12. package/src/commands/__fixtures__/sample_mesh_invalid_type.json +27 -0
  13. package/src/commands/__fixtures__/sample_mesh_mismatching_path.json +29 -0
  14. package/src/commands/__fixtures__/sample_mesh_outside_workspace_dir.json +23 -0
  15. package/src/commands/__fixtures__/sample_mesh_path_from_home.json +14 -0
  16. package/src/commands/__fixtures__/sample_mesh_subdirectory.json +23 -0
  17. package/src/commands/__fixtures__/sample_mesh_with_files_array.json +29 -0
  18. package/src/commands/api-mesh/__tests__/create.test.js +1000 -31
  19. package/src/commands/api-mesh/__tests__/get.test.js +8 -0
  20. package/src/commands/api-mesh/__tests__/init.test.js +390 -0
  21. package/src/commands/api-mesh/__tests__/update.test.js +419 -4
  22. package/src/commands/api-mesh/create.js +37 -68
  23. package/src/commands/api-mesh/get.js +7 -2
  24. package/src/commands/api-mesh/init.js +168 -0
  25. package/src/commands/api-mesh/source/__tests__/get.test.js +1 -1
  26. package/src/commands/api-mesh/source/__tests__/install.test.js +2 -2
  27. package/src/commands/api-mesh/update.js +35 -67
  28. package/src/helpers.js +249 -91
  29. package/src/lib/devConsole.js +1 -2
  30. package/src/templates/gitignore +1 -0
  31. package/src/templates/package.json +38 -0
  32. package/src/utils.js +329 -31
  33. package/src/meshInterpolation.js +0 -120
@@ -17,6 +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
21
  }));
21
22
  jest.mock('@adobe/aio-cli-lib-console', () => ({
22
23
  init: jest.fn().mockResolvedValue(mockConsoleCLIInstance),
@@ -34,7 +35,7 @@ const selectedWorkspace = { id: '123456789', title: 'Workspace01' };
34
35
  const { readFile } = require('fs/promises');
35
36
 
36
37
  const UpdateCommand = require('../update');
37
- const { initSdk, initRequestId, promptConfirm } = require('../../../helpers');
38
+ const { initSdk, initRequestId, promptConfirm, importFiles } = require('../../../helpers');
38
39
  const { getMeshId, updateMesh } = require('../../../lib/devConsole');
39
40
 
40
41
  let logSpy = null;
@@ -58,7 +59,7 @@ describe('update command tests', () => {
58
59
  logSpy = jest.spyOn(UpdateCommand.prototype, 'log');
59
60
  errorLogSpy = jest.spyOn(UpdateCommand.prototype, 'error');
60
61
 
61
- readFile.mockResolvedValue(true);
62
+ readFile.mockResolvedValue('{}');
62
63
 
63
64
  getMeshId.mockResolvedValue('mesh_id');
64
65
  updateMesh.mockResolvedValue({ status: 'success' });
@@ -74,6 +75,30 @@ describe('update command tests', () => {
74
75
  });
75
76
 
76
77
  test('should pass with valid args', async () => {
78
+ let sampleMesh = {
79
+ meshConfig: {
80
+ sources: [
81
+ {
82
+ name: '<api_name>',
83
+ handler: {
84
+ graphql: {
85
+ endpoint: '<gql_endpoint>',
86
+ },
87
+ },
88
+ },
89
+ ],
90
+ },
91
+ };
92
+ readFile.mockResolvedValue(JSON.stringify(sampleMesh));
93
+
94
+ parseSpy.mockResolvedValueOnce({
95
+ args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
96
+ flags: {
97
+ ignoreCache: mockIgnoreCacheFlag,
98
+ autoConfirmAction: mockAutoApproveAction,
99
+ },
100
+ });
101
+
77
102
  const runResult = await UpdateCommand.run();
78
103
 
79
104
  expect(runResult).toMatchInlineSnapshot(`
@@ -109,8 +134,24 @@ describe('update command tests', () => {
109
134
  });
110
135
 
111
136
  test('should pass with valid args and ignoreCache flag', async () => {
137
+ let sampleMesh = {
138
+ meshConfig: {
139
+ sources: [
140
+ {
141
+ name: '<api_name>',
142
+ handler: {
143
+ graphql: {
144
+ endpoint: '<gql_endpoint>',
145
+ },
146
+ },
147
+ },
148
+ ],
149
+ },
150
+ };
151
+ readFile.mockResolvedValue(JSON.stringify(sampleMesh));
152
+
112
153
  parseSpy.mockResolvedValueOnce({
113
- args: { file: 'valid_file_name' },
154
+ args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
114
155
  flags: {
115
156
  ignoreCache: Promise.resolve(true),
116
157
  autoConfirmAction: mockAutoApproveAction,
@@ -152,8 +193,24 @@ describe('update command tests', () => {
152
193
  });
153
194
 
154
195
  test('should pass with valid args if autoConfirmAction flag is set', async () => {
196
+ let sampleMesh = {
197
+ meshConfig: {
198
+ sources: [
199
+ {
200
+ name: '<api_name>',
201
+ handler: {
202
+ graphql: {
203
+ endpoint: '<gql_endpoint>',
204
+ },
205
+ },
206
+ },
207
+ ],
208
+ },
209
+ };
210
+ readFile.mockResolvedValue(JSON.stringify(sampleMesh));
211
+
155
212
  parseSpy.mockResolvedValueOnce({
156
- args: { file: 'valid_file_name' },
213
+ args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
157
214
  flags: {
158
215
  ignoreCache: mockIgnoreCacheFlag,
159
216
  autoConfirmAction: Promise.resolve(true),
@@ -196,6 +253,30 @@ describe('update command tests', () => {
196
253
  });
197
254
 
198
255
  test('should fail if mesh id is missing', async () => {
256
+ let sampleMesh = {
257
+ meshConfig: {
258
+ sources: [
259
+ {
260
+ name: '<api_name>',
261
+ handler: {
262
+ graphql: {
263
+ endpoint: '<gql_endpoint>',
264
+ },
265
+ },
266
+ },
267
+ ],
268
+ },
269
+ };
270
+ readFile.mockResolvedValue(JSON.stringify(sampleMesh));
271
+
272
+ parseSpy.mockResolvedValueOnce({
273
+ args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
274
+ flags: {
275
+ ignoreCache: mockIgnoreCacheFlag,
276
+ autoConfirmAction: mockAutoApproveAction,
277
+ },
278
+ });
279
+
199
280
  getMeshId.mockResolvedValue(null);
200
281
  const runResult = UpdateCommand.run();
201
282
 
@@ -213,6 +294,30 @@ describe('update command tests', () => {
213
294
  });
214
295
 
215
296
  test('should fail if getMeshId api failed', async () => {
297
+ let sampleMesh = {
298
+ meshConfig: {
299
+ sources: [
300
+ {
301
+ name: '<api_name>',
302
+ handler: {
303
+ graphql: {
304
+ endpoint: '<gql_endpoint>',
305
+ },
306
+ },
307
+ },
308
+ ],
309
+ },
310
+ };
311
+ readFile.mockResolvedValue(JSON.stringify(sampleMesh));
312
+
313
+ parseSpy.mockResolvedValueOnce({
314
+ args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
315
+ flags: {
316
+ ignoreCache: mockIgnoreCacheFlag,
317
+ autoConfirmAction: mockAutoApproveAction,
318
+ },
319
+ });
320
+
216
321
  getMeshId.mockRejectedValue(new Error('getMeshId api failed'));
217
322
  const runResult = UpdateCommand.run();
218
323
 
@@ -230,6 +335,30 @@ describe('update command tests', () => {
230
335
  });
231
336
 
232
337
  test('should fail if updateMesh method failed', async () => {
338
+ let sampleMesh = {
339
+ meshConfig: {
340
+ sources: [
341
+ {
342
+ name: '<api_name>',
343
+ handler: {
344
+ graphql: {
345
+ endpoint: '<gql_endpoint>',
346
+ },
347
+ },
348
+ },
349
+ ],
350
+ },
351
+ };
352
+ readFile.mockResolvedValue(JSON.stringify(sampleMesh));
353
+
354
+ parseSpy.mockResolvedValueOnce({
355
+ args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
356
+ flags: {
357
+ ignoreCache: mockIgnoreCacheFlag,
358
+ autoConfirmAction: mockAutoApproveAction,
359
+ },
360
+ });
361
+
233
362
  updateMesh.mockRejectedValueOnce(new Error('dummy_error'));
234
363
 
235
364
  const runResult = UpdateCommand.run();
@@ -308,6 +437,30 @@ describe('update command tests', () => {
308
437
  });
309
438
 
310
439
  test('should not update if user prompt returns false', async () => {
440
+ let sampleMesh = {
441
+ meshConfig: {
442
+ sources: [
443
+ {
444
+ name: '<api_name>',
445
+ handler: {
446
+ graphql: {
447
+ endpoint: '<gql_endpoint>',
448
+ },
449
+ },
450
+ },
451
+ ],
452
+ },
453
+ };
454
+ readFile.mockResolvedValue(JSON.stringify(sampleMesh));
455
+
456
+ parseSpy.mockResolvedValueOnce({
457
+ args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
458
+ flags: {
459
+ ignoreCache: mockIgnoreCacheFlag,
460
+ autoConfirmAction: mockAutoApproveAction,
461
+ },
462
+ });
463
+
311
464
  promptConfirm.mockResolvedValueOnce(false);
312
465
 
313
466
  const runResult = await UpdateCommand.run();
@@ -322,4 +475,266 @@ describe('update command tests', () => {
322
475
  `);
323
476
  expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
324
477
  });
478
+
479
+ test('should pass if there are local files in meshConfig i.e., the file is appended in files array', async () => {
480
+ let sampleMesh = {
481
+ meshConfig: {
482
+ sources: [
483
+ {
484
+ name: '<json_source_name>',
485
+ handler: {
486
+ JsonSchema: {
487
+ baseUrl: '<json_source__baseurl>',
488
+ operations: [
489
+ {
490
+ type: 'Query',
491
+ field: '<query>',
492
+ path: '<query_path>',
493
+ method: 'POST',
494
+ requestSchema: './requestParams.json',
495
+ },
496
+ ],
497
+ },
498
+ },
499
+ },
500
+ ],
501
+ },
502
+ };
503
+ readFile.mockResolvedValue(JSON.stringify(sampleMesh));
504
+
505
+ let meshConfig = {
506
+ sources: [
507
+ {
508
+ name: '<json_source_name>',
509
+ handler: {
510
+ JsonSchema: {
511
+ baseUrl: '<json_source__baseurl>',
512
+ operations: [
513
+ {
514
+ type: 'Query',
515
+ field: '<query>',
516
+ path: '<query_path>',
517
+ method: 'POST',
518
+ requestSchema: './requestParams.json',
519
+ },
520
+ ],
521
+ },
522
+ },
523
+ },
524
+ ],
525
+ files: [
526
+ {
527
+ path: './requestParams.json',
528
+ content: '{"type":"updatedContent"}',
529
+ },
530
+ ],
531
+ };
532
+
533
+ updateMesh.mockResolvedValue({
534
+ meshId: 'dummy_mesh_id',
535
+ meshConfig: meshConfig,
536
+ });
537
+
538
+ parseSpy.mockResolvedValue({
539
+ args: { file: 'src/commands/__fixtures__/sample_mesh_files.json' },
540
+ flags: {
541
+ autoConfirmAction: mockAutoApproveAction,
542
+ },
543
+ });
544
+
545
+ importFiles.mockResolvedValueOnce({
546
+ meshConfig,
547
+ });
548
+
549
+ const output = await UpdateCommand.run();
550
+
551
+ expect(initRequestId).toHaveBeenCalled();
552
+ expect(updateMesh.mock.calls[0]).toMatchInlineSnapshot(`
553
+ [
554
+ "1234",
555
+ "5678",
556
+ "123456789",
557
+ "mesh_id",
558
+ {
559
+ "meshConfig": {
560
+ "files": [
561
+ {
562
+ "content": "{"type":"updatedContent"}",
563
+ "path": "./requestParams.json",
564
+ },
565
+ ],
566
+ "sources": [
567
+ {
568
+ "handler": {
569
+ "JsonSchema": {
570
+ "baseUrl": "<json_source__baseurl>",
571
+ "operations": [
572
+ {
573
+ "field": "<query>",
574
+ "method": "POST",
575
+ "path": "<query_path>",
576
+ "requestSchema": "./requestParams.json",
577
+ "type": "Query",
578
+ },
579
+ ],
580
+ },
581
+ },
582
+ "name": "<json_source_name>",
583
+ },
584
+ ],
585
+ },
586
+ },
587
+ ]
588
+ `);
589
+
590
+ expect(output).toMatchInlineSnapshot(`
591
+ {
592
+ "meshConfig": {
593
+ "files": [
594
+ {
595
+ "content": "{"type":"updatedContent"}",
596
+ "path": "./requestParams.json",
597
+ },
598
+ ],
599
+ "sources": [
600
+ {
601
+ "handler": {
602
+ "JsonSchema": {
603
+ "baseUrl": "<json_source__baseurl>",
604
+ "operations": [
605
+ {
606
+ "field": "<query>",
607
+ "method": "POST",
608
+ "path": "<query_path>",
609
+ "requestSchema": "./requestParams.json",
610
+ "type": "Query",
611
+ },
612
+ ],
613
+ },
614
+ },
615
+ "name": "<json_source_name>",
616
+ },
617
+ ],
618
+ },
619
+ "meshId": "dummy_mesh_id",
620
+ }
621
+ `);
622
+ });
623
+
624
+ test('should fail if the input mesh config file is inavlid i.e., file name has more than 25 characters', async () => {
625
+ let sampleMesh = {
626
+ meshConfig: {
627
+ sources: [
628
+ {
629
+ name: '<json_source_name>',
630
+ handler: {
631
+ JsonSchema: {
632
+ baseUrl: '<json_source__baseurl>',
633
+ operations: [
634
+ {
635
+ type: 'Query',
636
+ field: '<query>',
637
+ path: '<query_path>',
638
+ method: 'POST',
639
+ requestSchema: './requestJSONParameters.json',
640
+ },
641
+ ],
642
+ },
643
+ },
644
+ },
645
+ ],
646
+ },
647
+ };
648
+ readFile.mockResolvedValue(JSON.stringify(sampleMesh));
649
+
650
+ parseSpy.mockResolvedValue({
651
+ args: { file: 'src/commands/__fixtures__/sample_mesh_invalid_file_name.json' },
652
+ flags: {
653
+ ignoreCache: mockIgnoreCacheFlag,
654
+ autoConfirmAction: mockAutoApproveAction,
655
+ },
656
+ });
657
+
658
+ const output = UpdateCommand.run();
659
+
660
+ await expect(output).rejects.toEqual(new Error('Input mesh config is not valid.'));
661
+
662
+ expect(logSpy.mock.calls).toMatchInlineSnapshot(`
663
+ [
664
+ [
665
+ "Mesh file names must be less than 25 characters. The following file(s) are invalid: requestJSONParameters.json.",
666
+ ],
667
+ ]
668
+ `);
669
+
670
+ expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
671
+ [
672
+ [
673
+ "Input mesh config is not valid.",
674
+ ],
675
+ ]
676
+ `);
677
+ });
678
+
679
+ test('should fail if the import files function fails', async () => {
680
+ let sampleMesh = {
681
+ meshConfig: {
682
+ sources: [
683
+ {
684
+ name: '<json_source_name>',
685
+ handler: {
686
+ JsonSchema: {
687
+ baseUrl: '<json_source__baseurl>',
688
+ operations: [
689
+ {
690
+ type: 'Query',
691
+ field: '<query>',
692
+ path: '<query_path>',
693
+ method: 'POST',
694
+ requestSchema: './requestParams.json',
695
+ },
696
+ ],
697
+ },
698
+ },
699
+ },
700
+ ],
701
+ },
702
+ };
703
+ readFile.mockResolvedValue(JSON.stringify(sampleMesh));
704
+
705
+ parseSpy.mockResolvedValue({
706
+ args: { file: 'src/commands/__fixtures__/sample_mesh_files.json' },
707
+ flags: {
708
+ ignoreCache: mockIgnoreCacheFlag,
709
+ autoConfirmAction: mockAutoApproveAction,
710
+ },
711
+ });
712
+
713
+ importFiles.mockImplementation(() => {
714
+ throw new Error('Error reading the file.');
715
+ });
716
+
717
+ const output = UpdateCommand.run();
718
+ await expect(output).rejects.toEqual(
719
+ new Error(
720
+ 'Unable to import the files in the mesh config. Please check the file and try again.',
721
+ ),
722
+ );
723
+
724
+ expect(logSpy.mock.calls).toMatchInlineSnapshot(`
725
+ [
726
+ [
727
+ "Error reading the file.",
728
+ ],
729
+ ]
730
+ `);
731
+
732
+ expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
733
+ [
734
+ [
735
+ "Unable to import the files in the mesh config. Please check the file and try again.",
736
+ ],
737
+ ]
738
+ `);
739
+ });
325
740
  });
@@ -10,22 +10,26 @@ governing permissions and limitations under the License.
10
10
  */
11
11
 
12
12
  const { Command } = require('@oclif/core');
13
- const { readFile } = require('fs/promises');
14
13
 
15
- const { initSdk, initRequestId, promptConfirm } = require('../../helpers');
14
+ const { initSdk, initRequestId, promptConfirm, importFiles } = require('../../helpers');
16
15
  const logger = require('../../classes/logger');
17
16
  const CONSTANTS = require('../../constants');
18
- const { ignoreCacheFlag, autoConfirmActionFlag, jsonFlag, envFileFlag } = require('../../utils');
17
+ const {
18
+ ignoreCacheFlag,
19
+ autoConfirmActionFlag,
20
+ jsonFlag,
21
+ getFilesInMeshConfig,
22
+ envFileFlag,
23
+ checkPlaceholders,
24
+ readFileContents,
25
+ validateAndInterpolateMesh,
26
+ } = require('../../utils');
19
27
  const {
20
28
  createMesh,
21
29
  createAPIMeshCredentials,
22
30
  subscribeCredentialToMeshService,
23
31
  } = require('../../lib/devConsole');
24
32
 
25
- const meshInterpolation = require('../../meshInterpolation');
26
-
27
- const dotenv = require('dotenv');
28
-
29
33
  const { MULTITENANT_GRAPHQL_SERVER_BASE_URL } = CONSTANTS;
30
34
 
31
35
  class CreateCommand extends Command {
@@ -54,82 +58,46 @@ class CreateCommand extends Command {
54
58
 
55
59
  const ignoreCache = await flags.ignoreCache;
56
60
  const autoConfirmAction = await flags.autoConfirmAction;
57
- const envFilePath=await flags.env;
61
+ const envFilePath = await flags.env;
58
62
  const { imsOrgId, projectId, workspaceId } = await initSdk({
59
63
  ignoreCache,
60
64
  });
61
65
 
62
- let inputMeshData;
63
-
64
66
  //Input the mesh data from the input file
65
- try {
66
- inputMeshData = await readFile(args.file, 'utf8');
67
- } catch (error) {
68
- logger.error(error);
69
-
70
- this.log(error.message);
71
- this.error(
72
- 'Unable to read the mesh configuration file provided. Please check the file and try again.',
73
- );
74
- }
67
+ let inputMeshData = await readFileContents(args.file, this, 'mesh');
75
68
 
76
69
  let data;
77
70
 
78
- if (envFilePath) {
79
- let envFileContent;
80
-
81
- //Read the environment file
71
+ if (checkPlaceholders(inputMeshData)) {
72
+ this.log('The provided mesh contains placeholders. Starting mesh interpolation process.');
73
+ data = await validateAndInterpolateMesh(inputMeshData, envFilePath, this);
74
+ } else {
82
75
  try {
83
- envFileContent = await readFile(envFilePath, 'utf8');
84
- } catch (error) {
85
- this.log(error.message);
86
- this.error('Unable to read the env file provided. Please check the file and try again.');
76
+ data = JSON.parse(inputMeshData);
77
+ } catch (err) {
78
+ this.log(err.message);
79
+ this.error('Input mesh file is not a valid JSON. Please check the file provided.');
87
80
  }
81
+ }
88
82
 
89
- //Validate the env file
90
- const envFileValidity = meshInterpolation.validateEnvFileFormat(envFileContent);
91
- if (envFileValidity.valid) {
92
- //load env file into the process.env object
93
- meshInterpolation.clearEnv();
94
-
95
- //Added env at start of each environment variable
96
- const envObj = { env: dotenv.config({ path: envFilePath }).parsed };
97
-
98
- let {
99
- interpolationStatus,
100
- missingKeys,
101
- interpolatedMeshData,
102
- } = await meshInterpolation.interpolateMesh(inputMeshData, envObj);
103
-
104
- //De-duplicate the missing keys array
105
- missingKeys = missingKeys.filter(function (item, index, inputArray) {
106
- return inputArray.indexOf(item) == index;
107
- });
108
-
109
- if (interpolationStatus == 'failed') {
110
- this.error(
111
- 'The mesh file cannot be interpolated due to missing keys : ' + missingKeys.toString(),
112
- );
113
- }
83
+ let filesList = [];
114
84
 
115
- try {
116
- data = JSON.parse(interpolatedMeshData);
117
- } catch (err) {
118
- this.log(err.message);
119
- this.log(interpolatedMeshData);
120
- this.error(
121
- 'Interpolated mesh is not a valid JSON. Please check the generated json file.',
122
- );
123
- }
124
- } else {
125
- this.error(`Issue in ${envFilePath} file - ` + envFileValidity.error);
126
- }
127
- } else {
85
+ try {
86
+ filesList = getFilesInMeshConfig(data, args.file);
87
+ } catch (err) {
88
+ this.log(err.message);
89
+ this.error('Input mesh config is not valid.');
90
+ }
91
+
92
+ // if local files are present, import them in files array in meshConfig
93
+ if (filesList.length) {
128
94
  try {
129
- data = JSON.parse(inputMeshData);
95
+ data = await importFiles(data, filesList, args.file, flags.autoConfirmAction);
130
96
  } catch (err) {
131
97
  this.log(err.message);
132
- this.error('Input mesh file is not a valid JSON. Please check the file provided.');
98
+ this.error(
99
+ 'Unable to import the files in the mesh config. Please check the file and try again.',
100
+ );
133
101
  }
134
102
  }
135
103
 
@@ -142,6 +110,7 @@ class CreateCommand extends Command {
142
110
  if (shouldContinue) {
143
111
  try {
144
112
  const mesh = await createMesh(imsOrgId, projectId, workspaceId, data);
113
+
145
114
  let sdkList = [];
146
115
 
147
116
  if (mesh) {
@@ -9,12 +9,12 @@ OF ANY KIND, either express or implied. See the License for the specific languag
9
9
  governing permissions and limitations under the License.
10
10
  */
11
11
 
12
- const { Command } = require('@oclif/command');
12
+ const { Command } = require('@oclif/core');
13
13
  const { writeFile } = require('fs/promises');
14
14
 
15
15
  const logger = require('../../classes/logger');
16
16
  const { initSdk, initRequestId } = require('../../helpers');
17
- const { ignoreCacheFlag } = require('../../utils');
17
+ const { ignoreCacheFlag, jsonFlag } = require('../../utils');
18
18
  const { getMeshId, getMesh } = require('../../lib/devConsole');
19
19
 
20
20
  require('dotenv').config();
@@ -23,8 +23,11 @@ class GetCommand extends Command {
23
23
  static args = [{ name: 'file' }];
24
24
  static flags = {
25
25
  ignoreCache: ignoreCacheFlag,
26
+ json: jsonFlag,
26
27
  };
27
28
 
29
+ static enableJsonFlag = true;
30
+
28
31
  async run() {
29
32
  await initRequestId();
30
33
 
@@ -33,9 +36,11 @@ class GetCommand extends Command {
33
36
  const { args, flags } = await this.parse(GetCommand);
34
37
 
35
38
  const ignoreCache = await flags.ignoreCache;
39
+ const json = await flags.json;
36
40
 
37
41
  const { imsOrgId, projectId, workspaceId } = await initSdk({
38
42
  ignoreCache,
43
+ verbose: !json,
39
44
  });
40
45
 
41
46
  let meshId = null;