@adobe/aio-cli-plugin-api-mesh 2.1.0 → 2.2.0-beta.2
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 +4 -2
- package/src/commands/__fixtures__/env_invalid +8 -0
- package/src/commands/__fixtures__/env_valid +3 -0
- 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/__fixtures__/sample_mesh_with_placeholder +17 -0
- package/src/commands/api-mesh/__tests__/create.test.js +1202 -1
- 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 +47 -14
- package/src/commands/api-mesh/init.js +168 -0
- package/src/commands/api-mesh/update.js +49 -17
- package/src/helpers.js +254 -3
- package/src/lib/devConsole.js +1 -2
- package/src/templates/gitignore +1 -0
- package/src/templates/package.json +38 -0
- package/src/utils.js +337 -33
|
@@ -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,20 +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
|
-
require('dotenv').config();
|
|
26
|
-
|
|
27
33
|
const { MULTITENANT_GRAPHQL_SERVER_BASE_URL } = CONSTANTS;
|
|
28
34
|
|
|
29
35
|
class CreateCommand extends Command {
|
|
@@ -32,6 +38,7 @@ class CreateCommand extends Command {
|
|
|
32
38
|
ignoreCache: ignoreCacheFlag,
|
|
33
39
|
autoConfirmAction: autoConfirmActionFlag,
|
|
34
40
|
json: jsonFlag,
|
|
41
|
+
env: envFileFlag,
|
|
35
42
|
};
|
|
36
43
|
|
|
37
44
|
static enableJsonFlag = true;
|
|
@@ -51,22 +58,47 @@ class CreateCommand extends Command {
|
|
|
51
58
|
|
|
52
59
|
const ignoreCache = await flags.ignoreCache;
|
|
53
60
|
const autoConfirmAction = await flags.autoConfirmAction;
|
|
54
|
-
|
|
61
|
+
const envFilePath = await flags.env;
|
|
55
62
|
const { imsOrgId, projectId, workspaceId } = await initSdk({
|
|
56
63
|
ignoreCache,
|
|
57
64
|
});
|
|
58
65
|
|
|
66
|
+
//Input the mesh data from the input file
|
|
67
|
+
let inputMeshData = await readFileContents(args.file, this, 'mesh');
|
|
68
|
+
|
|
59
69
|
let data;
|
|
60
70
|
|
|
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 {
|
|
75
|
+
try {
|
|
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.');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let filesList = [];
|
|
84
|
+
|
|
61
85
|
try {
|
|
62
|
-
|
|
63
|
-
} catch (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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) {
|
|
94
|
+
try {
|
|
95
|
+
data = await importFiles(data, filesList, args.file, flags.autoConfirmAction);
|
|
96
|
+
} catch (err) {
|
|
97
|
+
this.log(err.message);
|
|
98
|
+
this.error(
|
|
99
|
+
'Unable to import the files in the mesh config. Please check the file and try again.',
|
|
100
|
+
);
|
|
101
|
+
}
|
|
70
102
|
}
|
|
71
103
|
|
|
72
104
|
let shouldContinue = true;
|
|
@@ -78,6 +110,7 @@ class CreateCommand extends Command {
|
|
|
78
110
|
if (shouldContinue) {
|
|
79
111
|
try {
|
|
80
112
|
const mesh = await createMesh(imsOrgId, projectId, workspaceId, data);
|
|
113
|
+
|
|
81
114
|
let sdkList = [];
|
|
82
115
|
|
|
83
116
|
if (mesh) {
|