@adobe/aio-cli-plugin-api-mesh 2.2.0 → 2.2.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 +2 -1
- package/src/commands/__fixtures__/files/requestParams.json +3 -0
- package/src/commands/__fixtures__/openapi-schema.json +4 -0
- package/src/commands/__fixtures__/requestParams.json +3 -0
- package/src/commands/__fixtures__/sample_fully_qualified_mesh.json +29 -0
- package/src/commands/__fixtures__/sample_invalid_mesh.txt +17 -0
- package/src/commands/__fixtures__/sample_mesh_files.json +23 -0
- package/src/commands/__fixtures__/sample_mesh_invalid_file_content.json +14 -0
- package/src/commands/__fixtures__/sample_mesh_invalid_file_name.json +27 -0
- package/src/commands/__fixtures__/sample_mesh_invalid_paths.json +23 -0
- package/src/commands/__fixtures__/sample_mesh_invalid_type.json +27 -0
- package/src/commands/__fixtures__/sample_mesh_mismatching_path.json +29 -0
- package/src/commands/__fixtures__/sample_mesh_outside_workspace_dir.json +23 -0
- package/src/commands/__fixtures__/sample_mesh_path_from_home.json +14 -0
- package/src/commands/__fixtures__/sample_mesh_subdirectory.json +23 -0
- package/src/commands/__fixtures__/sample_mesh_with_files_array.json +29 -0
- package/src/commands/api-mesh/__tests__/create.test.js +1000 -31
- package/src/commands/api-mesh/__tests__/get.test.js +8 -0
- package/src/commands/api-mesh/__tests__/init.test.js +390 -0
- package/src/commands/api-mesh/__tests__/update.test.js +419 -4
- package/src/commands/api-mesh/create.js +37 -68
- package/src/commands/api-mesh/get.js +7 -2
- package/src/commands/api-mesh/init.js +168 -0
- package/src/commands/api-mesh/source/__tests__/get.test.js +1 -1
- package/src/commands/api-mesh/source/__tests__/install.test.js +2 -2
- package/src/commands/api-mesh/update.js +35 -67
- package/src/helpers.js +249 -91
- package/src/lib/devConsole.js +1 -2
- package/src/templates/gitignore +1 -0
- package/src/templates/package.json +38 -0
- package/src/utils.js +329 -31
- 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(
|
|
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: '
|
|
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: '
|
|
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 {
|
|
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
|
-
|
|
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 (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
84
|
-
} catch (
|
|
85
|
-
this.log(
|
|
86
|
-
this.error('
|
|
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
|
-
|
|
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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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 =
|
|
95
|
+
data = await importFiles(data, filesList, args.file, flags.autoConfirmAction);
|
|
130
96
|
} catch (err) {
|
|
131
97
|
this.log(err.message);
|
|
132
|
-
this.error(
|
|
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/
|
|
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;
|