@jupiterone/integration-sdk-cli 8.3.0 → 8.4.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.
Files changed (48) hide show
  1. package/dist/src/commands/collect.d.ts +2 -0
  2. package/dist/src/commands/collect.js +50 -5
  3. package/dist/src/commands/collect.js.map +1 -1
  4. package/dist/src/commands/diff.js +3 -3
  5. package/dist/src/commands/diff.js.map +1 -1
  6. package/dist/src/commands/document.js +2 -2
  7. package/dist/src/commands/document.js.map +1 -1
  8. package/dist/src/commands/neo4j.js +4 -4
  9. package/dist/src/commands/neo4j.js.map +1 -1
  10. package/dist/src/commands/run.js +13 -13
  11. package/dist/src/commands/run.js.map +1 -1
  12. package/dist/src/commands/sync.js +7 -7
  13. package/dist/src/commands/sync.js.map +1 -1
  14. package/dist/src/commands/validate-question-file.js +4 -4
  15. package/dist/src/commands/validate-question-file.js.map +1 -1
  16. package/dist/src/commands/visualize-types.js +3 -3
  17. package/dist/src/commands/visualize-types.js.map +1 -1
  18. package/dist/src/commands/visualize.js +2 -2
  19. package/dist/src/commands/visualize.js.map +1 -1
  20. package/dist/src/config.js +1 -1
  21. package/dist/src/config.js.map +1 -1
  22. package/dist/src/index.js +10 -10
  23. package/dist/src/index.js.map +1 -1
  24. package/dist/src/log.js +1 -0
  25. package/dist/src/log.js.map +1 -1
  26. package/dist/src/neo4j/neo4jGraphStore.js +8 -8
  27. package/dist/src/neo4j/neo4jGraphStore.js.map +1 -1
  28. package/dist/src/neo4j/uploadToNeo4j.js +2 -2
  29. package/dist/src/neo4j/uploadToNeo4j.js.map +1 -1
  30. package/dist/src/services/queryLanguage.js +1 -1
  31. package/dist/src/services/queryLanguage.js.map +1 -1
  32. package/dist/src/utils/generateVisHTML.js +1 -1
  33. package/dist/src/utils/generateVisHTML.js.map +1 -1
  34. package/dist/src/utils/getSortedJupiterOneTypes.js +2 -2
  35. package/dist/src/utils/getSortedJupiterOneTypes.js.map +1 -1
  36. package/dist/src/visualization/createMappedRelationshipNodesAndEdges.js +9 -9
  37. package/dist/src/visualization/createMappedRelationshipNodesAndEdges.js.map +1 -1
  38. package/dist/src/visualization/generateVisualization.js +6 -6
  39. package/dist/src/visualization/generateVisualization.js.map +1 -1
  40. package/dist/src/visualization/retrieveIntegrationData.js +1 -1
  41. package/dist/src/visualization/retrieveIntegrationData.js.map +1 -1
  42. package/dist/src/visualization/utils.js +2 -2
  43. package/dist/src/visualization/utils.js.map +1 -1
  44. package/dist/tsconfig.dist.tsbuildinfo +1 -10704
  45. package/package.json +7 -4
  46. package/src/__tests__/cli.test.ts +78 -0
  47. package/src/commands/collect.ts +66 -2
  48. package/src/log.ts +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupiterone/integration-sdk-cli",
3
- "version": "8.3.0",
3
+ "version": "8.4.1",
4
4
  "description": "The SDK for developing JupiterOne integrations",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -22,8 +22,10 @@
22
22
  "prepack": "yarn build:dist"
23
23
  },
24
24
  "dependencies": {
25
- "@jupiterone/integration-sdk-runtime": "^8.3.0",
25
+ "@jupiterone/integration-sdk-runtime": "^8.4.1",
26
+ "chalk": "^4",
26
27
  "commander": "^5.0.0",
28
+ "fs-extra": "^10.0.0",
27
29
  "globby": "^11.0.0",
28
30
  "js-yaml": "^4.1.0",
29
31
  "json-diff": "^0.5.4",
@@ -35,10 +37,11 @@
35
37
  "vis": "^4.21.0-EOL"
36
38
  },
37
39
  "devDependencies": {
38
- "@jupiterone/integration-sdk-private-test-utils": "^8.3.0",
40
+ "@jupiterone/integration-sdk-private-test-utils": "^8.4.1",
39
41
  "@pollyjs/adapter-node-http": "^5.1.1",
40
42
  "@pollyjs/core": "^5.1.1",
41
43
  "@pollyjs/persister-fs": "^5.1.1",
44
+ "@types/fs-extra": "^9.0.13",
42
45
  "@types/js-yaml": "^4.0.3",
43
46
  "@types/json-diff": "^0.5.1",
44
47
  "@types/lodash": "^4.14.158",
@@ -50,5 +53,5 @@
50
53
  "neo-forgery": "^2.0.0",
51
54
  "uuid": "^8.2.0"
52
55
  },
53
- "gitHead": "c0aadb45b32b5266fd4710a632f6b6a5144c548d"
56
+ "gitHead": "07778e4a5f0e87137f6036ee8e3ba4e44ff2f4bb"
54
57
  }
@@ -48,6 +48,84 @@ describe('collect', () => {
48
48
  loadProjectStructure('instanceWithDependentSteps');
49
49
  });
50
50
 
51
+ test('option --no-cache requires option --step', async () => {
52
+ await expect(
53
+ createCli().parseAsync([
54
+ 'node',
55
+ 'j1-integration',
56
+ 'collect',
57
+ '--no-cache',
58
+ ]),
59
+ ).rejects.toThrowError(
60
+ 'Invalid option: Option --no-cache requires option --step to also be specified.',
61
+ );
62
+ });
63
+ test('option --cache-path requires option --step', async () => {
64
+ await expect(
65
+ createCli().parseAsync([
66
+ 'node',
67
+ 'j1-integration',
68
+ 'collect',
69
+ '--cache-path',
70
+ './',
71
+ ]),
72
+ ).rejects.toThrowError(
73
+ 'Invalid option: Option --cache-path requires option --step to also be specified.',
74
+ );
75
+ });
76
+
77
+ test('Uses cache when --step flag is provided w/out --no-cache', async () => {
78
+ loadProjectStructure('instanceWithDependentCachedSteps');
79
+
80
+ await createCli().parseAsync([
81
+ 'node',
82
+ 'j1-integration',
83
+ 'collect',
84
+ '--step',
85
+ 'fetch-groups',
86
+ '--cache-path',
87
+ process.cwd(),
88
+ ]);
89
+
90
+ expect(log.displayExecutionResults).toHaveBeenCalledTimes(1);
91
+ expect(log.displayExecutionResults).toHaveBeenCalledWith({
92
+ integrationStepResults: [
93
+ {
94
+ id: 'fetch-accounts',
95
+ name: 'Fetch Accounts',
96
+ declaredTypes: ['my_account'],
97
+ dependsOn: undefined,
98
+ partialTypes: [],
99
+ encounteredTypes: ['test_account'],
100
+ status: StepResultStatus.CACHED,
101
+ },
102
+ {
103
+ id: 'fetch-groups',
104
+ dependsOn: ['fetch-accounts'],
105
+ name: 'Fetch Groups',
106
+ declaredTypes: ['my_groups'],
107
+ partialTypes: [],
108
+ encounteredTypes: [],
109
+ status: StepResultStatus.SUCCESS,
110
+ },
111
+ {
112
+ id: 'fetch-users',
113
+ name: 'Fetch Users',
114
+ declaredTypes: ['my_user'],
115
+ dependsOn: undefined,
116
+ partialTypes: [],
117
+ encounteredTypes: [],
118
+ status: StepResultStatus.DISABLED,
119
+ },
120
+ ],
121
+ metadata: {
122
+ partialDatasets: {
123
+ types: [],
124
+ },
125
+ },
126
+ });
127
+ });
128
+
51
129
  test('loads the integration, executes it, and logs the result', async () => {
52
130
  await createCli().parseAsync(['node', 'j1-integration', 'collect']);
53
131
 
@@ -1,9 +1,11 @@
1
1
  import { createCommand } from 'commander';
2
2
  import path from 'path';
3
+ import fs from 'fs-extra';
3
4
 
4
5
  import {
5
6
  executeIntegrationLocally,
6
7
  FileSystemGraphObjectStore,
8
+ getRootStorageDirectory,
7
9
  prepareLocalStepCollection,
8
10
  } from '@jupiterone/integration-sdk-runtime';
9
11
 
@@ -26,12 +28,31 @@ export function collect() {
26
28
  )
27
29
  .option(
28
30
  '-s, --step <steps>',
29
- 'step(s) to run, comma separated',
31
+ 'step(s) to run, comma separated. Utilizes available caches to speed up dependent steps.',
30
32
  collector,
31
33
  [],
32
34
  )
35
+ .option(
36
+ '--no-cache',
37
+ 'Can be used with the `--step` flag to disable the use of the cache.',
38
+ )
39
+ .option(
40
+ '--cache-path <filepath>',
41
+ 'Can be used with the `--step` to specify a path to a non-default cache location.',
42
+ )
33
43
  .option('-V, --disable-schema-validation', 'disable schema validation')
34
44
  .action(async (options) => {
45
+ if (!options.cache && options.step.length === 0) {
46
+ throw new Error(
47
+ 'Invalid option: Option --no-cache requires option --step to also be specified.',
48
+ );
49
+ }
50
+ if (options.cachePath && options.step.length === 0) {
51
+ throw new Error(
52
+ 'Invalid option: Option --cache-path requires option --step to also be specified.',
53
+ );
54
+ }
55
+
35
56
  // Point `fileSystem.ts` functions to expected location relative to
36
57
  // integration project path.
37
58
  process.env.JUPITERONE_INTEGRATION_STORAGE_DIRECTORY = path.resolve(
@@ -39,9 +60,21 @@ export function collect() {
39
60
  '.j1-integration',
40
61
  );
41
62
 
63
+ if (options.step.length > 0 && options.cache && !options.cachePath) {
64
+ // Step option was used, cache is wanted, and no cache path was provided
65
+ // therefore, copy .j1-integration into .j1-integration-cache
66
+ await buildCacheFromJ1Integration();
67
+ }
68
+
42
69
  const config = prepareLocalStepCollection(
43
70
  await loadConfig(path.join(options.projectPath, 'src')),
44
- options,
71
+ {
72
+ ...options,
73
+ dependenciesCache: {
74
+ enabled: options.cache,
75
+ filepath: getRootCacheDirectory(options.cachePath),
76
+ },
77
+ },
45
78
  );
46
79
  log.info('\nConfiguration loaded! Running integration...\n');
47
80
 
@@ -67,3 +100,34 @@ export function collect() {
67
100
  log.displayExecutionResults(results);
68
101
  });
69
102
  }
103
+
104
+ export const DEFAULT_CACHE_DIRECTORY_NAME = '.j1-integration-cache';
105
+
106
+ export function getRootCacheDirectory(filepath?: string) {
107
+ return path.resolve(
108
+ typeof filepath === 'string' ? filepath : process.cwd(),
109
+ DEFAULT_CACHE_DIRECTORY_NAME,
110
+ );
111
+ }
112
+
113
+ /**
114
+ * Builds the step cache from the .j1-integration/graph directory
115
+ * by moving the files to .j1-integration-cache.
116
+ */
117
+ async function buildCacheFromJ1Integration() {
118
+ const sourceGraphDirectory = path.join(getRootStorageDirectory(), 'graph');
119
+ const destinationGraphDirectory = path.join(getRootCacheDirectory(), 'graph');
120
+
121
+ const sourceExists = await fs.pathExists(sourceGraphDirectory);
122
+ if (sourceExists) {
123
+ await fs
124
+ .move(sourceGraphDirectory, destinationGraphDirectory, {
125
+ overwrite: true,
126
+ })
127
+ .catch((error) => {
128
+ log.error(`Failed to seed .j1-integration-cache from .j1-integration`);
129
+ log.error(error);
130
+ });
131
+ log.info(`Populated the .j1-integration-cache from .j1-integration.`);
132
+ }
133
+ }
package/src/log.ts CHANGED
@@ -100,6 +100,7 @@ function logStepStatus(stepResult: IntegrationStepResult) {
100
100
  function getStepStatusText(status: StepResultStatus) {
101
101
  switch (status) {
102
102
  case StepResultStatus.SUCCESS:
103
+ case StepResultStatus.CACHED:
103
104
  return chalk.green(status);
104
105
  case StepResultStatus.FAILURE:
105
106
  return chalk.red(status);