@adobe/aio-cli-plugin-api-mesh 2.3.0 → 2.3.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.
@@ -1 +1 @@
1
- {"version":"2.3.0","commands":{"PLUGINNAME":{"id":"PLUGINNAME","description":"Your description here","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio PLUGINNAME:some_command"],"flags":{"someflag":{"name":"someflag","type":"option","char":"f","description":"this is some flag"}},"args":[]},"api-mesh:create":{"id":"api-mesh:create","description":"Create a mesh with the given config.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false},"json":{"name":"json","type":"boolean","description":"Output JSON","allowNo":false},"env":{"name":"env","type":"option","char":"e","description":"Path to env file","default":".env"}},"args":[{"name":"file"}]},"api-mesh:delete":{"id":"api-mesh:delete","description":"Delete the config of a given mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false}},"args":[]},"api-mesh:describe":{"id":"api-mesh:describe","description":"Get details of a mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[]},"api-mesh:get":{"id":"api-mesh:get","description":"Get the config of a given mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"json":{"name":"json","type":"boolean","description":"Output JSON","allowNo":false}},"args":[{"name":"file"}]},"api-mesh:init":{"id":"api-mesh:init","description":"This command will create a workspace where you can organise your API mesh configuration and other files","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":[{"description":"API mesh workspace init","command":"aio api-mesh init commerce-mesh"},{"description":"API mesh workspace init with flags","command":"aio api-mesh init commerce-mesh --path ./mesh_projects/test_mesh --git y --packageManager yarn"}],"flags":{"path":{"name":"path","type":"option","char":"p","default":"."},"packageManager":{"name":"packageManager","type":"option","char":"m","options":["npm","yarn"]},"git":{"name":"git","type":"option","char":"g","options":["y","n"]}},"args":[{"name":"projectName","description":"Project name","required":true}]},"api-mesh:status":{"id":"api-mesh:status","description":"Get a mesh status with a given meshid.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[]},"api-mesh:update":{"id":"api-mesh:update","description":"Update a mesh with the given config.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false},"env":{"name":"env","type":"option","char":"e","description":"Path to env file","default":".env"}},"args":[{"name":"file"}]},"api-mesh:source:discover":{"id":"api-mesh:source:discover","description":"Return the list of avaliable sources","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm install action prompt. CLI will not check ask user to install source.","allowNo":false}},"args":[]},"api-mesh:source:get":{"id":"api-mesh:source:get","description":"Command returns the content of a specific source.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio api-mesh:source:get -s=<version>@<source_name>","$ aio api-mesh:source:get -s<source_name>","$ aio api-mesh:source:get -m"],"flags":{"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm print action prompt. CLI will not check ask user to print source.","allowNo":false},"source":{"name":"source","type":"option","char":"s","description":"Source name"},"multiple":{"name":"multiple","type":"boolean","char":"m","description":"Select multiple sources","allowNo":false}},"args":[]},"api-mesh:source:install":{"id":"api-mesh:source:install","description":"Command to install the source to your API mesh.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio api-mesh:source:install <version>@<source_name>","$ aio api-mesh:source:install <source_name> -v <variable_name>=<variable_value>","$ aio api-mesh:source:install <source_name> -f <path_to_variables_file>"],"flags":{"source":{"name":"source","type":"option","char":"s","description":"Source name"},"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm override action prompt. CLI will not check ask user to override source.","allowNo":false},"variable":{"name":"variable","type":"option","char":"v","description":"Variables required for the source"},"variable-file":{"name":"variable-file","type":"option","char":"f","description":"Variables file path"},"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[{"name":"source"}]}}}
1
+ {"version":"2.3.2","commands":{"PLUGINNAME":{"id":"PLUGINNAME","description":"Your description here","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio PLUGINNAME:some_command"],"flags":{"someflag":{"name":"someflag","type":"option","char":"f","description":"this is some flag"}},"args":[]},"api-mesh:create":{"id":"api-mesh:create","description":"Create a mesh with the given config.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false},"json":{"name":"json","type":"boolean","description":"Output JSON","allowNo":false},"env":{"name":"env","type":"option","char":"e","description":"Path to env file","default":".env"}},"args":[{"name":"file"}]},"api-mesh:delete":{"id":"api-mesh:delete","description":"Delete the config of a given mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false}},"args":[]},"api-mesh:describe":{"id":"api-mesh:describe","description":"Get details of a mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[]},"api-mesh:get":{"id":"api-mesh:get","description":"Get the config of a given mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"json":{"name":"json","type":"boolean","description":"Output JSON","allowNo":false}},"args":[{"name":"file"}]},"api-mesh:init":{"id":"api-mesh:init","description":"This command will create a workspace where you can organise your API mesh configuration and other files","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":[{"description":"API mesh workspace init","command":"aio api-mesh init commerce-mesh"},{"description":"API mesh workspace init with flags","command":"aio api-mesh init commerce-mesh --path ./mesh_projects/test_mesh --git y --packageManager yarn"}],"flags":{"path":{"name":"path","type":"option","char":"p","default":"."},"packageManager":{"name":"packageManager","type":"option","char":"m","options":["npm","yarn"]},"git":{"name":"git","type":"option","char":"g","options":["y","n"]}},"args":[{"name":"projectName","description":"Project name","required":true}]},"api-mesh:status":{"id":"api-mesh:status","description":"Get a mesh status with a given meshid.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[]},"api-mesh:update":{"id":"api-mesh:update","description":"Update a mesh with the given config.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false},"env":{"name":"env","type":"option","char":"e","description":"Path to env file","default":".env"}},"args":[{"name":"file"}]},"api-mesh:source:discover":{"id":"api-mesh:source:discover","description":"Return the list of avaliable sources","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm install action prompt. CLI will not check ask user to install source.","allowNo":false}},"args":[]},"api-mesh:source:get":{"id":"api-mesh:source:get","description":"Command returns the content of a specific source.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio api-mesh:source:get -s=<version>@<source_name>","$ aio api-mesh:source:get -s<source_name>","$ aio api-mesh:source:get -m"],"flags":{"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm print action prompt. CLI will not check ask user to print source.","allowNo":false},"source":{"name":"source","type":"option","char":"s","description":"Source name"},"multiple":{"name":"multiple","type":"boolean","char":"m","description":"Select multiple sources","allowNo":false}},"args":[]},"api-mesh:source:install":{"id":"api-mesh:source:install","description":"Command to install the source to your API mesh.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio api-mesh:source:install <version>@<source_name>","$ aio api-mesh:source:install <source_name> -v <variable_name>=<variable_value>","$ aio api-mesh:source:install <source_name> -f <path_to_variables_file>"],"flags":{"source":{"name":"source","type":"option","char":"s","description":"Source name"},"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm override action prompt. CLI will not check ask user to override source.","allowNo":false},"variable":{"name":"variable","type":"option","char":"v","description":"Variables required for the source"},"variable-file":{"name":"variable-file","type":"option","char":"f","description":"Variables file path"},"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[{"name":"source"}]}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/aio-cli-plugin-api-mesh",
3
- "version": "2.3.0",
3
+ "version": "2.3.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -0,0 +1,42 @@
1
+ {
2
+ "meshConfig": {
3
+ "sources": [
4
+ {
5
+ "name": "<json_source_name>",
6
+ "handler": {
7
+ "JsonSchema": {
8
+ "baseUrl": "<json_source__baseurl>",
9
+ "operations": [
10
+ {
11
+ "type": "Query",
12
+ "field": "<query>",
13
+ "path": "<query_path>",
14
+ "method": "POST",
15
+ "requestSchema": "./requestParams.json"
16
+ }
17
+ ]
18
+ }
19
+ }
20
+ }
21
+ ],
22
+ "plugins": [
23
+ {
24
+ "hooks": {
25
+ "beforeAll": {
26
+ "composer": "./hooks.js#functionName"
27
+ }
28
+ }
29
+ }
30
+ ],
31
+ "files": [
32
+ {
33
+ "path": "./requestParams.json",
34
+ "content": "{\"type\":\"dummyContent\"}"
35
+ },
36
+ {
37
+ "path": "./hooks.js",
38
+ "content": "module.exports.functionName = () => { console.log('beforeAll hook'); }"
39
+ }
40
+ ]
41
+ }
42
+ }
@@ -14,6 +14,7 @@ const mockConsoleCLIInstance = {};
14
14
 
15
15
  const CreateCommand = require('../create');
16
16
  const sampleCreateMeshConfig = require('../../__fixtures__/sample_mesh.json');
17
+ const meshConfigWithComposerFiles = require('../../__fixtures__/sample_mesh_with_composer_files.json');
17
18
  const {
18
19
  initSdk,
19
20
  initRequestId,
@@ -22,6 +23,7 @@ const {
22
23
  importFiles,
23
24
  } = require('../../../helpers');
24
25
  const {
26
+ getMesh,
25
27
  createMesh,
26
28
  createAPIMeshCredentials,
27
29
  subscribeCredentialToMeshService,
@@ -82,6 +84,12 @@ describe('create command tests', () => {
82
84
  });
83
85
  subscribeCredentialToMeshService.mockResolvedValue(['dummy_service']);
84
86
 
87
+ let fetchedMeshConfig = sampleCreateMeshConfig;
88
+ fetchedMeshConfig.meshId = 'dummy_id';
89
+ fetchedMeshConfig.meshURL = '';
90
+
91
+ getMesh.mockResolvedValue(fetchedMeshConfig);
92
+
85
93
  parseSpy = jest.spyOn(CreateCommand.prototype, 'parse');
86
94
  parseSpy.mockResolvedValue({
87
95
  args: { file: 'src/commands/__fixtures__/sample_mesh.json' },
@@ -158,6 +166,78 @@ describe('create command tests', () => {
158
166
  `);
159
167
  expect(CreateCommand.aliases).toMatchInlineSnapshot(`[]`);
160
168
  });
169
+
170
+ test('should pass if a valid mesh config file with composer files are provided', async () => {
171
+ createMesh.mockResolvedValueOnce({
172
+ meshId: 'dummy_mesh_id',
173
+ meshConfig: meshConfigWithComposerFiles.meshConfig,
174
+ });
175
+
176
+ parseSpy.mockResolvedValueOnce({
177
+ args: { file: 'src/commands/__fixtures__/sample_mesh_with_composer_files.json' },
178
+ flags: {
179
+ autoConfirmAction: Promise.resolve(true),
180
+ },
181
+ });
182
+
183
+ const output = await CreateCommand.run();
184
+
185
+ expect(output).toMatchInlineSnapshot(`
186
+ {
187
+ "adobeIdIntegrationsForWorkspace": {
188
+ "apiKey": "dummy_api_key",
189
+ "id": "dummy_id",
190
+ },
191
+ "mesh": {
192
+ "meshConfig": {
193
+ "files": [
194
+ {
195
+ "content": "{"type":"dummyContent"}",
196
+ "path": "./requestParams.json",
197
+ },
198
+ {
199
+ "content": "module.exports.functionName = () => { console.log('beforeAll hook'); }",
200
+ "path": "./hooks.js",
201
+ },
202
+ ],
203
+ "plugins": [
204
+ {
205
+ "hooks": {
206
+ "beforeAll": {
207
+ "composer": "./hooks.js#functionName",
208
+ },
209
+ },
210
+ },
211
+ ],
212
+ "sources": [
213
+ {
214
+ "handler": {
215
+ "JsonSchema": {
216
+ "baseUrl": "<json_source__baseurl>",
217
+ "operations": [
218
+ {
219
+ "field": "<query>",
220
+ "method": "POST",
221
+ "path": "<query_path>",
222
+ "requestSchema": "./requestParams.json",
223
+ "type": "Query",
224
+ },
225
+ ],
226
+ },
227
+ },
228
+ "name": "<json_source_name>",
229
+ },
230
+ ],
231
+ },
232
+ "meshId": "dummy_mesh_id",
233
+ },
234
+ "sdkList": [
235
+ "dummy_service",
236
+ ],
237
+ }
238
+ `);
239
+ });
240
+
161
241
  test('should fail if create mesh api has failed', async () => {
162
242
  createMesh.mockRejectedValueOnce(new Error('create mesh api failed'));
163
243
 
@@ -182,6 +262,7 @@ describe('create command tests', () => {
182
262
  ]
183
263
  `);
184
264
  });
265
+
185
266
  test('should create if a valid mesh config file is provided', async () => {
186
267
  const runResult = await CreateCommand.run();
187
268
 
@@ -284,6 +365,113 @@ describe('create command tests', () => {
284
365
  expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
285
366
  });
286
367
 
368
+ test('should create and return Ti mesh url if a valid mesh config file for TI client is provided', async () => {
369
+ let fetchedMeshConfig = sampleCreateMeshConfig;
370
+ fetchedMeshConfig.meshId = 'dummy_id';
371
+ fetchedMeshConfig.meshURL = 'https://tigraph.adobe.io';
372
+ getMesh.mockResolvedValueOnce(fetchedMeshConfig);
373
+
374
+ const runResult = await CreateCommand.run();
375
+
376
+ expect(initRequestId).toHaveBeenCalled();
377
+ expect(createMesh.mock.calls[0]).toMatchInlineSnapshot(`
378
+ [
379
+ "1234",
380
+ "5678",
381
+ "123456789",
382
+ {
383
+ "meshConfig": {
384
+ "sources": [
385
+ {
386
+ "handler": {
387
+ "graphql": {
388
+ "endpoint": "<gql_endpoint>",
389
+ },
390
+ },
391
+ "name": "<api_name>",
392
+ },
393
+ ],
394
+ },
395
+ },
396
+ ]
397
+ `);
398
+ expect(createAPIMeshCredentials.mock.calls[0]).toMatchInlineSnapshot(`
399
+ [
400
+ "1234",
401
+ "5678",
402
+ "123456789",
403
+ ]
404
+ `);
405
+ expect(subscribeCredentialToMeshService.mock.calls[0]).toMatchInlineSnapshot(`
406
+ [
407
+ "1234",
408
+ "5678",
409
+ "123456789",
410
+ "dummy_id",
411
+ ]
412
+ `);
413
+ expect(runResult).toMatchInlineSnapshot(`
414
+ {
415
+ "adobeIdIntegrationsForWorkspace": {
416
+ "apiKey": "dummy_api_key",
417
+ "id": "dummy_id",
418
+ },
419
+ "mesh": {
420
+ "meshConfig": {
421
+ "sources": [
422
+ {
423
+ "handler": {
424
+ "graphql": {
425
+ "endpoint": "<gql_endpoint>",
426
+ },
427
+ },
428
+ "name": "<api_name>",
429
+ },
430
+ ],
431
+ },
432
+ "meshId": "dummy_mesh_id",
433
+ },
434
+ "sdkList": [
435
+ "dummy_service",
436
+ ],
437
+ }
438
+ `);
439
+ expect(logSpy.mock.calls).toMatchInlineSnapshot(`
440
+ [
441
+ [
442
+ "******************************************************************************************************",
443
+ ],
444
+ [
445
+ "Your mesh is being provisioned. Wait a few minutes before checking the status of your mesh %s",
446
+ "dummy_mesh_id",
447
+ ],
448
+ [
449
+ "To check the status of your mesh, run:",
450
+ ],
451
+ [
452
+ "aio api-mesh:status",
453
+ ],
454
+ [
455
+ "******************************************************************************************************",
456
+ ],
457
+ [
458
+ "Successfully created API Key %s",
459
+ "dummy_api_key",
460
+ ],
461
+ [
462
+ "Successfully subscribed API Key %s to API Mesh service",
463
+ "dummy_api_key",
464
+ ],
465
+ [
466
+ "Mesh Endpoint: %s
467
+ ",
468
+ "https://tigraph.adobe.io/dummy_mesh_id/graphql?api_key=dummy_api_key",
469
+ ],
470
+ ]
471
+ `);
472
+ expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
473
+ });
474
+
287
475
  test('should fail if mesh config file arg is missing', async () => {
288
476
  parseSpy.mockResolvedValueOnce({
289
477
  args: {},
@@ -639,7 +827,7 @@ describe('create command tests', () => {
639
827
  });
640
828
 
641
829
  test('should successfully create a mesh if provided env file is valid, mesh interpolation is successful and interpolated mesh is a valid JSON', async () => {
642
- parseSpy.mockResolvedValue({
830
+ parseSpy.mockResolvedValueOnce({
643
831
  args: { file: 'src/commands/__fixtures__/sample_mesh_with_placeholder' },
644
832
  flags: {
645
833
  ignoreCache: mockIgnoreCacheFlag,
@@ -690,7 +878,7 @@ describe('create command tests', () => {
690
878
  });
691
879
 
692
880
  test('should return error if inputMesh is not a valid JSON', async () => {
693
- parseSpy.mockResolvedValue({
881
+ parseSpy.mockResolvedValueOnce({
694
882
  args: { file: 'src/commands/__fixtures__/sample_invalid_mesh.txt' },
695
883
  flags: {
696
884
  ignoreCache: mockIgnoreCacheFlag,
@@ -741,12 +929,12 @@ describe('create command tests', () => {
741
929
  ],
742
930
  };
743
931
 
744
- createMesh.mockResolvedValue({
932
+ createMesh.mockResolvedValueOnce({
745
933
  meshId: 'dummy_mesh_id',
746
934
  meshConfig: meshConfig,
747
935
  });
748
936
 
749
- parseSpy.mockResolvedValue({
937
+ parseSpy.mockResolvedValueOnce({
750
938
  args: { file: 'src/commands/__fixtures__/sample_mesh_files.json' },
751
939
  flags: {
752
940
  autoConfirmAction: Promise.resolve(false),
@@ -856,7 +1044,7 @@ describe('create command tests', () => {
856
1044
  });
857
1045
 
858
1046
  test('should fail if the file name is more than 25 characters', async () => {
859
- parseSpy.mockResolvedValue({
1047
+ parseSpy.mockResolvedValueOnce({
860
1048
  args: { file: 'src/commands/__fixtures__/sample_mesh_invalid_file_name.json' },
861
1049
  flags: {
862
1050
  autoConfirmAction: Promise.resolve(false),
@@ -884,36 +1072,8 @@ describe('create command tests', () => {
884
1072
  `);
885
1073
  });
886
1074
 
887
- test('should fail if the file paths in files array and filenames in sources, transforms, additionalResolvers do not match in mesh config', async () => {
888
- parseSpy.mockResolvedValue({
889
- args: { file: 'src/commands/__fixtures__/sample_mesh_mismatching_path.json' },
890
- flags: {
891
- autoConfirmAction: Promise.resolve(false),
892
- },
893
- });
894
-
895
- const output = CreateCommand.run();
896
-
897
- await expect(output).rejects.toEqual(new Error('Input mesh config is not valid.'));
898
-
899
- expect(logSpy.mock.calls).toMatchInlineSnapshot(`
900
- [
901
- [
902
- "Please make sure the file names are matching in meshConfig.",
903
- ],
904
- ]
905
- `);
906
- expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`
907
- [
908
- [
909
- "Input mesh config is not valid.",
910
- ],
911
- ]
912
- `);
913
- });
914
-
915
1075
  test('should fail if the file is of type other than js, json extension', async () => {
916
- parseSpy.mockResolvedValue({
1076
+ parseSpy.mockResolvedValueOnce({
917
1077
  args: { file: 'src/commands/__fixtures__/sample_mesh_invalid_type.json' },
918
1078
  flags: {
919
1079
  autoConfirmAction: Promise.resolve(false),
@@ -941,7 +1101,7 @@ describe('create command tests', () => {
941
1101
  });
942
1102
 
943
1103
  test('should fail if the files do not exist in the mesh directory or subdirectory', async () => {
944
- parseSpy.mockResolvedValue({
1104
+ parseSpy.mockResolvedValueOnce({
945
1105
  args: { file: 'src/commands/__fixtures__/sample_mesh_invalid_paths.json' },
946
1106
  flags: {
947
1107
  autoConfirmAction: Promise.resolve(false),
@@ -979,7 +1139,7 @@ describe('create command tests', () => {
979
1139
  });
980
1140
 
981
1141
  test('should fail if import files function fails', async () => {
982
- parseSpy.mockResolvedValue({
1142
+ parseSpy.mockResolvedValueOnce({
983
1143
  args: { file: 'src/commands/__fixtures__/sample_mesh_files.json' },
984
1144
  flags: {
985
1145
  autoConfirmAction: Promise.resolve(false),
@@ -1044,19 +1204,19 @@ describe('create command tests', () => {
1044
1204
  ],
1045
1205
  };
1046
1206
 
1047
- promptConfirm.mockResolvedValue(false).mockResolvedValue(true);
1207
+ promptConfirm.mockResolvedValueOnce(false).mockResolvedValueOnce(true);
1048
1208
 
1049
- importFiles.mockResolvedValue(meshConfig);
1209
+ importFiles.mockResolvedValueOnce(meshConfig);
1050
1210
 
1051
- createMesh.mockResolvedValue({
1211
+ createMesh.mockResolvedValueOnce({
1052
1212
  meshId: 'dummy_mesh_id',
1053
1213
  meshConfig: meshConfig,
1054
1214
  });
1055
1215
 
1056
- parseSpy.mockResolvedValue({
1216
+ parseSpy.mockResolvedValueOnce({
1057
1217
  args: { file: 'src/commands/__fixtures__/sample_mesh_with_files_array.json' },
1058
1218
  flags: {
1059
- autoConfirmAction: Promise.resolve(false),
1219
+ autoConfirmAction: Promise.resolve(true),
1060
1220
  },
1061
1221
  });
1062
1222
 
@@ -1184,12 +1344,12 @@ describe('create command tests', () => {
1184
1344
  ],
1185
1345
  };
1186
1346
 
1187
- promptConfirm.mockResolvedValue(true).mockResolvedValue(true);
1347
+ promptConfirm.mockResolvedValueOnce(true).mockResolvedValueOnce(true);
1188
1348
 
1189
- parseSpy.mockResolvedValue({
1349
+ parseSpy.mockResolvedValueOnce({
1190
1350
  args: { file: 'src/commands/__fixtures__/sample_mesh_with_files_array.json' },
1191
1351
  flags: {
1192
- autoConfirmAction: Promise.resolve(false),
1352
+ autoConfirmAction: Promise.resolve(true),
1193
1353
  },
1194
1354
  });
1195
1355
 
@@ -1197,7 +1357,7 @@ describe('create command tests', () => {
1197
1357
  meshConfig,
1198
1358
  });
1199
1359
 
1200
- createMesh.mockResolvedValue({
1360
+ createMesh.mockResolvedValueOnce({
1201
1361
  meshId: 'dummy_mesh_id',
1202
1362
  meshConfig: meshConfig,
1203
1363
  });
@@ -1329,20 +1489,20 @@ describe('create command tests', () => {
1329
1489
  ],
1330
1490
  };
1331
1491
 
1332
- parseSpy.mockResolvedValue({
1492
+ parseSpy.mockResolvedValueOnce({
1333
1493
  args: { file: 'src/commands/__fixtures__/sample_fully_qualified_mesh.json' },
1334
1494
  flags: {
1335
- autoConfirmAction: Promise.resolve(false),
1495
+ autoConfirmAction: Promise.resolve(true),
1336
1496
  },
1337
1497
  });
1338
1498
 
1339
- promptConfirm.mockResolvedValue(true);
1499
+ promptConfirm.mockResolvedValueOnce(true);
1340
1500
 
1341
1501
  importFiles.mockResolvedValueOnce({
1342
1502
  meshConfig,
1343
1503
  });
1344
1504
 
1345
- createMesh.mockResolvedValue({
1505
+ createMesh.mockResolvedValueOnce({
1346
1506
  meshId: 'dummy_mesh_id',
1347
1507
  meshConfig: meshConfig,
1348
1508
  });
@@ -1473,15 +1633,15 @@ describe('create command tests', () => {
1473
1633
  ],
1474
1634
  };
1475
1635
 
1476
- createMesh.mockResolvedValue({
1636
+ createMesh.mockResolvedValueOnce({
1477
1637
  meshId: 'dummy_mesh_id',
1478
1638
  meshConfig: meshConfig,
1479
1639
  });
1480
1640
 
1481
- parseSpy.mockResolvedValue({
1641
+ parseSpy.mockResolvedValueOnce({
1482
1642
  args: { file: 'src/commands/__fixtures__/sample_mesh_subdirectory.json' },
1483
1643
  flags: {
1484
- autoConfirmAction: Promise.resolve(false),
1644
+ autoConfirmAction: Promise.resolve(true),
1485
1645
  },
1486
1646
  });
1487
1647
 
@@ -1588,7 +1748,7 @@ describe('create command tests', () => {
1588
1748
  });
1589
1749
 
1590
1750
  test('should fail if the file is outside the workspace directory', async () => {
1591
- parseSpy.mockResolvedValue({
1751
+ parseSpy.mockResolvedValueOnce({
1592
1752
  args: { file: 'src/commands/__fixtures__/sample_mesh_outside_workspace_dir.json' },
1593
1753
  flags: {
1594
1754
  autoConfirmAction: Promise.resolve(false),
@@ -1615,7 +1775,7 @@ describe('create command tests', () => {
1615
1775
  });
1616
1776
 
1617
1777
  test('should fail if the file has invalid JSON content', async () => {
1618
- parseSpy.mockResolvedValue({
1778
+ parseSpy.mockResolvedValueOnce({
1619
1779
  args: { file: 'src/commands/__fixtures__/sample_mesh_invalid_file_content.json' },
1620
1780
  flags: {
1621
1781
  autoConfirmAction: Promise.resolve(false),
@@ -1652,7 +1812,7 @@ describe('create command tests', () => {
1652
1812
  });
1653
1813
 
1654
1814
  test('should fail if the file path starts from home directory i.e., path starts with ~/', async () => {
1655
- parseSpy.mockResolvedValue({
1815
+ parseSpy.mockResolvedValueOnce({
1656
1816
  args: { file: 'src/commands/__fixtures__/sample_mesh_path_from_home.json' },
1657
1817
  flags: {
1658
1818
  autoConfirmAction: Promise.resolve(false),
@@ -28,7 +28,8 @@ jest.mock('../../../lib/devConsole');
28
28
 
29
29
  const DescribeCommand = require('../describe');
30
30
  const { initSdk, initRequestId } = require('../../../helpers');
31
- const { describeMesh } = require('../../../lib/devConsole');
31
+ const { describeMesh, getMesh } = require('../../../lib/devConsole');
32
+ const sampleCreateMeshConfig = require('../../__fixtures__/sample_mesh.json');
32
33
 
33
34
  const selectedOrg = { id: '1234', code: 'CODE1234@AdobeOrg', name: 'ORG01', type: 'entp' };
34
35
  const selectedProject = { id: '5678', title: 'Project01' };
@@ -64,6 +65,12 @@ describe('describe command tests', () => {
64
65
  ignoreCache: mockIgnoreCacheFlag,
65
66
  },
66
67
  });
68
+
69
+ let fetchedMeshConfig = sampleCreateMeshConfig;
70
+ fetchedMeshConfig.meshId = 'dummy_id';
71
+ fetchedMeshConfig.meshURL = '';
72
+
73
+ getMesh.mockResolvedValue(fetchedMeshConfig);
67
74
  });
68
75
 
69
76
  afterEach(() => {
@@ -172,7 +179,7 @@ describe('describe command tests', () => {
172
179
  expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
173
180
  });
174
181
 
175
- test('should succeed if valid details are provided', async () => {
182
+ test('should return Non TI url if request is Non Ti', async () => {
176
183
  const runResult = await DescribeCommand.run();
177
184
 
178
185
  expect(initRequestId).toHaveBeenCalled();
@@ -219,6 +226,61 @@ describe('describe command tests', () => {
219
226
  "https://graph.adobe.io/api/dummy_meshId/graphql?api_key=dummy_apiKey",
220
227
  ],
221
228
  ]
229
+ `);
230
+ });
231
+
232
+ test('should return Ti URL if api return TI url', async () => {
233
+ let fetchedMeshConfig = sampleCreateMeshConfig;
234
+ fetchedMeshConfig.meshId = 'dummy_id';
235
+ fetchedMeshConfig.meshURL = 'https://tigraph.adobe.io';
236
+
237
+ getMesh.mockResolvedValue(fetchedMeshConfig);
238
+ const runResult = await DescribeCommand.run();
239
+
240
+ expect(initRequestId).toHaveBeenCalled();
241
+ expect(describeMesh).toHaveBeenCalledWith(
242
+ selectedOrg.id,
243
+ selectedProject.id,
244
+ selectedWorkspace.id,
245
+ );
246
+ expect(runResult).toMatchInlineSnapshot(`
247
+ {
248
+ "apiKey": "dummy_apiKey",
249
+ "meshId": "dummy_meshId",
250
+ }
251
+ `);
252
+ expect(logSpy.mock.calls).toMatchInlineSnapshot(`
253
+ [
254
+ [
255
+ "Successfully retrieved mesh details
256
+ ",
257
+ ],
258
+ [
259
+ "Org ID: %s",
260
+ "1234",
261
+ ],
262
+ [
263
+ "Project ID: %s",
264
+ "5678",
265
+ ],
266
+ [
267
+ "Workspace ID: %s",
268
+ "123456789",
269
+ ],
270
+ [
271
+ "Mesh ID: %s",
272
+ "dummy_meshId",
273
+ ],
274
+ [
275
+ "API Key: %s",
276
+ "dummy_apiKey",
277
+ ],
278
+ [
279
+ "Mesh Endpoint: %s
280
+ ",
281
+ "https://tigraph.adobe.io/dummy_meshId/graphql?api_key=dummy_apiKey",
282
+ ],
283
+ ]
222
284
  `);
223
285
  expect(errorLogSpy.mock.calls).toMatchInlineSnapshot(`[]`);
224
286
  });
@@ -25,6 +25,7 @@ const {
25
25
  validateAndInterpolateMesh,
26
26
  } = require('../../utils');
27
27
  const {
28
+ getMesh,
28
29
  createMesh,
29
30
  createAPIMeshCredentials,
30
31
  subscribeCredentialToMeshService,
@@ -150,9 +151,15 @@ class CreateCommand extends Command {
150
151
  adobeIdIntegrationsForWorkspace.apiKey,
151
152
  );
152
153
 
154
+ const { meshURL } = await getMesh(imsOrgId, projectId, workspaceId, mesh.meshId);
155
+ const meshUrl =
156
+ meshURL === '' || meshURL === undefined
157
+ ? MULTITENANT_GRAPHQL_SERVER_BASE_URL
158
+ : meshURL;
159
+
153
160
  this.log(
154
161
  'Mesh Endpoint: %s\n',
155
- `${MULTITENANT_GRAPHQL_SERVER_BASE_URL}/${mesh.meshId}/graphql?api_key=${adobeIdIntegrationsForWorkspace.apiKey}`,
162
+ `${meshUrl}/${mesh.meshId}/graphql?api_key=${adobeIdIntegrationsForWorkspace.apiKey}`,
156
163
  );
157
164
  } else {
158
165
  this.log(
@@ -15,7 +15,7 @@ const logger = require('../../classes/logger');
15
15
  const { initSdk, initRequestId } = require('../../helpers');
16
16
  const CONSTANTS = require('../../constants');
17
17
  const { ignoreCacheFlag } = require('../../utils');
18
- const { describeMesh } = require('../../lib/devConsole');
18
+ const { describeMesh, getMesh } = require('../../lib/devConsole');
19
19
 
20
20
  require('dotenv').config();
21
21
 
@@ -52,12 +52,12 @@ class DescribeCommand extends Command {
52
52
  this.log('Workspace ID: %s', workspaceId);
53
53
  this.log('Mesh ID: %s', meshId);
54
54
 
55
+ const { meshURL } = await getMesh(imsOrgId, projectId, workspaceId, meshId);
56
+ const meshUrl = meshURL === '' ? MULTITENANT_GRAPHQL_SERVER_BASE_URL : meshURL;
57
+
55
58
  if (apiKey) {
56
59
  this.log('API Key: %s', apiKey);
57
- this.log(
58
- 'Mesh Endpoint: %s\n',
59
- `${MULTITENANT_GRAPHQL_SERVER_BASE_URL}/${meshId}/graphql?api_key=${apiKey}`,
60
- );
60
+ this.log('Mesh Endpoint: %s\n', `${meshUrl}/${meshId}/graphql?api_key=${apiKey}`);
61
61
  }
62
62
 
63
63
  return meshDetails;
package/src/utils.js CHANGED
@@ -88,7 +88,9 @@ function getFilesInMeshConfig(data, meshConfigName) {
88
88
  data.meshConfig.sources.transforms?.forEach(transform => {
89
89
  transform.replaceField?.replacements.forEach(replacement => {
90
90
  if (replacement.composer && !fileURLRegex.test(replacement.composer)) {
91
- filesList.push(replacement.composer);
91
+ const [filename] = replacement.composer.split('#');
92
+
93
+ filesList.push(filename);
92
94
  }
93
95
  });
94
96
  });
@@ -97,16 +99,51 @@ function getFilesInMeshConfig(data, meshConfigName) {
97
99
  data.meshConfig.transforms?.forEach(transform => {
98
100
  transform.replaceField?.replacements.forEach(replacement => {
99
101
  if (replacement.composer && !fileURLRegex.test(replacement.composer)) {
100
- filesList.push(replacement.composer);
102
+ const [filename] = replacement.composer.split('#');
103
+
104
+ filesList.push(filename);
101
105
  }
102
106
  });
103
107
  });
104
108
 
109
+ // Hooks Plugin - mesh level
110
+ data.meshConfig.plugins?.forEach(plugin => {
111
+ if (plugin.hooks) {
112
+ if (plugin.hooks.beforeAll) {
113
+ const composer = plugin.hooks.beforeAll.composer;
114
+
115
+ if (composer && !fileURLRegex.test(composer)) {
116
+ const [filename] = composer.split('#');
117
+
118
+ filesList.push(filename);
119
+ }
120
+ }
121
+ }
122
+ });
123
+
124
+ // OnFetch plugin - mesh level
125
+ data.meshConfig.plugins?.forEach(plugin => {
126
+ if (plugin.onFetch) {
127
+ plugin.onFetch.forEach(onFetchConfig => {
128
+ const handler = onFetchConfig.handler;
129
+
130
+ if (handler) {
131
+ filesList.push(handler);
132
+ }
133
+ });
134
+ }
135
+ });
136
+
137
+ // remove duplicate files
138
+ filesList = [...new Set(filesList)];
139
+
140
+ logger.info(`Files to be imported: ${filesList.join(', ')}`);
141
+
105
142
  try {
106
143
  if (filesList.length) {
107
144
  checkFilesAreUnderMeshDirectory(filesList, meshConfigName);
108
145
  validateFileType(filesList);
109
- validateFileName(filesList, data);
146
+ validateFileName(filesList);
110
147
  }
111
148
  } catch (err) {
112
149
  logger.error(err.message);
@@ -226,9 +263,8 @@ function validateFileType(filesList) {
226
263
  * Validate the filenames
227
264
  *
228
265
  * @param filesList Files in sources, tranforms or additionalResolvers in the meshConfig
229
- * @param data MeshConfig
230
266
  */
231
- function validateFileName(filesList, data) {
267
+ function validateFileName(filesList) {
232
268
  const filesWithInvalidNames = [];
233
269
 
234
270
  // Check if the file names are less than 25 characters
@@ -244,17 +280,6 @@ function validateFileName(filesList, data) {
244
280
  `Mesh file names must be less than 25 characters. The following file(s) are invalid: ${filesWithInvalidNames}.`,
245
281
  );
246
282
  }
247
-
248
- // check if the the filePaths in the files array match
249
- // the fileNames in sources, transforms or additionalResolvers
250
-
251
- if (data.meshConfig.files) {
252
- for (let i = 0; i < data.meshConfig.files.length; i++) {
253
- if (filesList.indexOf(data.meshConfig.files[i].path) == -1) {
254
- throw new Error(`Please make sure the file names are matching in meshConfig.`);
255
- }
256
- }
257
- }
258
283
  }
259
284
 
260
285
  /**validates the environment file content