@jupiterone/integration-sdk-cli 8.3.1 → 8.4.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.
Files changed (68) 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 +7 -5
  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 +4 -4
  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 +3 -2
  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 +15 -14
  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/neo4j/wipeNeo4j.js.map +1 -1
  31. package/dist/src/services/queryLanguage.js +1 -1
  32. package/dist/src/services/queryLanguage.js.map +1 -1
  33. package/dist/src/utils/generateVisHTML.js +1 -1
  34. package/dist/src/utils/generateVisHTML.js.map +1 -1
  35. package/dist/src/utils/getSortedJupiterOneTypes.js +2 -2
  36. package/dist/src/utils/getSortedJupiterOneTypes.js.map +1 -1
  37. package/dist/src/visualization/createMappedRelationshipNodesAndEdges.js +9 -9
  38. package/dist/src/visualization/createMappedRelationshipNodesAndEdges.js.map +1 -1
  39. package/dist/src/visualization/generateVisualization.js +6 -6
  40. package/dist/src/visualization/generateVisualization.js.map +1 -1
  41. package/dist/src/visualization/retrieveIntegrationData.js +1 -1
  42. package/dist/src/visualization/retrieveIntegrationData.js.map +1 -1
  43. package/dist/src/visualization/utils.d.ts +1 -1
  44. package/dist/src/visualization/utils.js +2 -2
  45. package/dist/src/visualization/utils.js.map +1 -1
  46. package/dist/tsconfig.dist.tsbuildinfo +1 -10704
  47. package/package.json +6 -4
  48. package/src/__tests__/cli.test.ts +78 -0
  49. package/src/commands/collect.ts +66 -2
  50. package/src/commands/document.ts +10 -9
  51. package/src/commands/neo4j.ts +16 -10
  52. package/src/commands/visualize-types.ts +7 -9
  53. package/src/config.ts +2 -1
  54. package/src/log.ts +1 -0
  55. package/src/neo4j/README.md +15 -18
  56. package/src/neo4j/__tests__/neo4jGraphStore.test.ts +55 -53
  57. package/src/neo4j/__tests__/neo4jUtilities.test.ts +27 -9
  58. package/src/neo4j/index.ts +1 -1
  59. package/src/neo4j/neo4jGraphStore.ts +39 -25
  60. package/src/neo4j/uploadToNeo4j.ts +5 -2
  61. package/src/neo4j/wipeNeo4j.ts +15 -11
  62. package/src/visualization/__tests__/createMappedRelationshipNodesAndEdges.test.ts +35 -49
  63. package/src/visualization/generateVisualization.ts +7 -12
  64. package/src/visualization/retrieveIntegrationData.ts +3 -5
  65. package/src/visualization/types/IntegrationData.ts +5 -1
  66. package/src/visualization/utils.ts +7 -4
  67. package/tsconfig.dist.json +1 -3
  68. package/tsconfig.json +1 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupiterone/integration-sdk-cli",
3
- "version": "8.3.1",
3
+ "version": "8.4.2",
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,9 +22,10 @@
22
22
  "prepack": "yarn build:dist"
23
23
  },
24
24
  "dependencies": {
25
- "@jupiterone/integration-sdk-runtime": "^8.3.1",
25
+ "@jupiterone/integration-sdk-runtime": "^8.4.2",
26
26
  "chalk": "^4",
27
27
  "commander": "^5.0.0",
28
+ "fs-extra": "^10.0.0",
28
29
  "globby": "^11.0.0",
29
30
  "js-yaml": "^4.1.0",
30
31
  "json-diff": "^0.5.4",
@@ -36,10 +37,11 @@
36
37
  "vis": "^4.21.0-EOL"
37
38
  },
38
39
  "devDependencies": {
39
- "@jupiterone/integration-sdk-private-test-utils": "^8.3.1",
40
+ "@jupiterone/integration-sdk-private-test-utils": "^8.4.2",
40
41
  "@pollyjs/adapter-node-http": "^5.1.1",
41
42
  "@pollyjs/core": "^5.1.1",
42
43
  "@pollyjs/persister-fs": "^5.1.1",
44
+ "@types/fs-extra": "^9.0.13",
43
45
  "@types/js-yaml": "^4.0.3",
44
46
  "@types/json-diff": "^0.5.1",
45
47
  "@types/lodash": "^4.14.158",
@@ -51,5 +53,5 @@
51
53
  "neo-forgery": "^2.0.0",
52
54
  "uuid": "^8.2.0"
53
55
  },
54
- "gitHead": "b730a382d3a7cd7b2b2c219af2b8bc13c059521f"
56
+ "gitHead": "1504c547765bd8636a8adcaf19098bc1b9f802e1"
55
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
+ }
@@ -68,9 +68,8 @@ async function executeDocumentAction(
68
68
  );
69
69
  log.info('\nExisting documentation file successfully loaded!\n');
70
70
 
71
- const newGeneratedDocumentationSection = generateGraphObjectDocumentationFromStepsMetadata(
72
- metadata,
73
- );
71
+ const newGeneratedDocumentationSection =
72
+ generateGraphObjectDocumentationFromStepsMetadata(metadata);
74
73
 
75
74
  log.info('\nGenerated integration documentation section:');
76
75
  log.info('---------------------------------------------\n');
@@ -187,9 +186,10 @@ ${generatedEntityTable}`;
187
186
  }
188
187
 
189
188
  if (metadata.relationships.length) {
190
- const generatedRelationshipTable = generateRelationshipTableFromAllStepEntityMetadata(
191
- metadata.relationships,
192
- );
189
+ const generatedRelationshipTable =
190
+ generateRelationshipTableFromAllStepEntityMetadata(
191
+ metadata.relationships,
192
+ );
193
193
 
194
194
  relationshipSection += `
195
195
 
@@ -201,9 +201,10 @@ ${generatedRelationshipTable}`;
201
201
  }
202
202
 
203
203
  if (metadata.mappedRelationships?.length) {
204
- const generatedMappedRelationshipTable = generateMappedRelationshipTableFromAllStepEntityMetadata(
205
- metadata.mappedRelationships,
206
- );
204
+ const generatedMappedRelationshipTable =
205
+ generateMappedRelationshipTableFromAllStepEntityMetadata(
206
+ metadata.mappedRelationships,
207
+ );
207
208
 
208
209
  mappedRelationshipSection += `
209
210
 
@@ -11,7 +11,9 @@ export function neo4j() {
11
11
  dotenvExpand(dotenv.config());
12
12
 
13
13
  const program = new commander.Command();
14
- program.description(`Suite of neo4j commands. Options are currently 'neo4j push', 'neo4j wipe', and 'neo4j wipe-all'`);
14
+ program.description(
15
+ `Suite of neo4j commands. Options are currently 'neo4j push', 'neo4j wipe', and 'neo4j wipe-all'`,
16
+ );
15
17
  const neo4jCommand = program.command('neo4j');
16
18
  neo4jCommand
17
19
  .command('push')
@@ -24,7 +26,7 @@ export function neo4j() {
24
26
  .option(
25
27
  '-i, --integration-instance-id <id>',
26
28
  '_integrationInstanceId assigned to uploaded entities',
27
- 'defaultLocalInstanceID'
29
+ 'defaultLocalInstanceID',
28
30
  )
29
31
  .action(async (options) => {
30
32
  log.info(`Beginning data upload to local neo4j`);
@@ -34,30 +36,34 @@ export function neo4j() {
34
36
  process.env.JUPITERONE_INTEGRATION_STORAGE_DIRECTORY = finalDir;
35
37
 
36
38
  await uploadToNeo4j({
37
- pathToData: finalDir,
38
- integrationInstanceID: options.integrationInstanceId
39
+ pathToData: finalDir,
40
+ integrationInstanceID: options.integrationInstanceId,
39
41
  });
40
42
  log.info(`Data uploaded to local neo4j`);
41
43
  });
42
44
 
43
- neo4jCommand
45
+ neo4jCommand
44
46
  .command('wipe')
45
- .description('wipe entities and relationships for a given integrationInstanceID in the Neo4j database')
47
+ .description(
48
+ 'wipe entities and relationships for a given integrationInstanceID in the Neo4j database',
49
+ )
46
50
  .option(
47
51
  '-i, --integration-instance-id <id>',
48
52
  '_integrationInstanceId assigned to uploaded entities',
49
- 'defaultLocalInstanceID'
53
+ 'defaultLocalInstanceID',
50
54
  )
51
55
  .action(async (options) => {
52
- await wipeNeo4jByID({integrationInstanceID: options.integrationInstanceId});
56
+ await wipeNeo4jByID({
57
+ integrationInstanceID: options.integrationInstanceId,
58
+ });
53
59
  });
54
60
 
55
- neo4jCommand
61
+ neo4jCommand
56
62
  .command('wipe-all')
57
63
  .description('wipe all entities and relationships in the Neo4j database')
58
64
  .action(async (options) => {
59
65
  await wipeAllNeo4j({});
60
66
  });
61
67
 
62
- return neo4jCommand;
68
+ return neo4jCommand;
63
69
  }
@@ -138,15 +138,13 @@ export function getNodesAndEdgesFromStepMetadata(
138
138
  types: options?.types,
139
139
  },
140
140
  );
141
- const {
142
- placeholderEntityNodes,
143
- mappedRelationshipEdges,
144
- } = getNodesAndEdgesFromStepMappedRelationshipMetadata(
145
- metadata.mappedRelationships || [],
146
- {
147
- types: options?.types,
148
- },
149
- );
141
+ const { placeholderEntityNodes, mappedRelationshipEdges } =
142
+ getNodesAndEdgesFromStepMappedRelationshipMetadata(
143
+ metadata.mappedRelationships || [],
144
+ {
145
+ types: options?.types,
146
+ },
147
+ );
150
148
  const entityNodes = getNodesFromStepEntityMetadata(metadata.entities, {
151
149
  types: options?.types,
152
150
  edges: [...relationshipEdges, ...mappedRelationshipEdges],
package/src/config.ts CHANGED
@@ -43,7 +43,8 @@ export function loadInvocationConfig(
43
43
  integrationModule = require(path.resolve(projectSourceDirectory, 'index'));
44
44
  } catch (err) {
45
45
  throw new IntegrationInvocationConfigLoadError(
46
- 'Error loading integration invocation configuration. Ensure "invocationConfig" is exported from "src/index". Additional details: ' + err,
46
+ 'Error loading integration invocation configuration. Ensure "invocationConfig" is exported from "src/index". Additional details: ' +
47
+ err,
47
48
  );
48
49
  }
49
50
 
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);
@@ -2,16 +2,13 @@
2
2
 
3
3
  ## Installation
4
4
 
5
- This command assumes you have three additional values stored in your
6
- local .env file:
7
- NEO4J_URI
8
- NEO4J_USER
9
- NEO4J_PASSWORD
5
+ This command assumes you have three additional values stored in your local .env
6
+ file: NEO4J_URI NEO4J_USER NEO4J_PASSWORD
10
7
 
11
- This can be used for uploading to local or remote Neo4j databases. If
12
- SSL is needed for a remote connection, specify `bolt+s` or `bolt+ssc`
13
- in the URI. For easy access to a local Neo4j instance, you can launch
14
- one via a Neo4j provided Docker image with the command:
8
+ This can be used for uploading to local or remote Neo4j databases. If SSL is
9
+ needed for a remote connection, specify `bolt+s` or `bolt+ssc` in the URI. For
10
+ easy access to a local Neo4j instance, you can launch one via a Neo4j provided
11
+ Docker image with the command:
15
12
 
16
13
  ```
17
14
  docker run \
@@ -25,18 +22,18 @@ docker run \
25
22
  neo4j:latest
26
23
  ```
27
24
 
28
- If you would like to use a different username and password, the NEO4J_AUTH
29
- value can be modified to whatever username/password you prefer.
25
+ If you would like to use a different username and password, the NEO4J_AUTH value
26
+ can be modified to whatever username/password you prefer.
30
27
 
31
- NOTE: Future updates are planned to streamline this without removing
32
- the option of pushing to an external Neo4j database.
28
+ NOTE: Future updates are planned to streamline this without removing the option
29
+ of pushing to an external Neo4j database.
33
30
 
34
31
  ## Usage
35
32
 
36
33
  Data is still collected in the same way as before with a call to `yarn start`.
37
34
 
38
- Once data has been collected, you can run `j1-integration neo4j push`. This will
39
- push data to the Neo4j server listed in the NEO4J_URI .env parameter. If
40
- running locally, you can then access data in the Neo4j database by visiting
41
- http://localhost:7474. Alternatively, you can download the full Neo4j
42
- Desktop application at https://neo4j.com/download/.
35
+ Once data has been collected, you can run `j1-integration neo4j push`. This will
36
+ push data to the Neo4j server listed in the NEO4J_URI .env parameter. If running
37
+ locally, you can then access data in the Neo4j database by visiting
38
+ http://localhost:7474. Alternatively, you can download the full Neo4j Desktop
39
+ application at https://neo4j.com/download/.
@@ -1,63 +1,66 @@
1
- import {
2
- mockDriver,
3
- mockSessionFromQuerySet,
4
- QuerySpec
5
- } from 'neo-forgery';
1
+ import { mockDriver, mockSessionFromQuerySet, QuerySpec } from 'neo-forgery';
6
2
  import * as neo4j from 'neo4j-driver';
7
3
  import { Neo4jGraphStore } from '../neo4jGraphStore';
8
4
  import { Entity, Relationship } from '@jupiterone/integration-sdk-core';
9
5
 
10
6
  const testInstanceID = 'testInstanceID';
11
- const testEntityData: Entity[] = [{
12
- _type: "testType",
13
- _class: "testClass",
14
- _key: "testKey",
15
- }];
16
- const testRelationshipData: Relationship[] = [{
17
- _fromEntityKey: "testKey1",
18
- _toEntityKey: "testKey2",
19
- _type: "testRelType",
20
- _key: "relKey",
21
- _class: "testRelationshipClass",
22
- }];
23
- const constraintCall = 'CREATE CONSTRAINT unique_testType IF NOT EXISTS ON (n:testType) ASSERT n._key IS UNIQUE;'
7
+ const testEntityData: Entity[] = [
8
+ {
9
+ _type: 'testType',
10
+ _class: 'testClass',
11
+ _key: 'testKey',
12
+ },
13
+ ];
14
+ const testRelationshipData: Relationship[] = [
15
+ {
16
+ _fromEntityKey: 'testKey1',
17
+ _toEntityKey: 'testKey2',
18
+ _type: 'testRelType',
19
+ _key: 'relKey',
20
+ _class: 'testRelationshipClass',
21
+ },
22
+ ];
23
+ const constraintCall =
24
+ 'CREATE CONSTRAINT unique_testType IF NOT EXISTS ON (n:testType) ASSERT n._key IS UNIQUE;';
24
25
  const addEntityCall = `MERGE (n:testType {_key: 'testKey', _integrationInstanceID: '${testInstanceID}'}) SET n._type = 'testType', n._class = 'testClass';`;
25
26
  const addRelationshipCall = `
26
27
  MATCH (start {_key: 'testKey1', _integrationInstanceID: '${testInstanceID}'})
27
28
  MATCH (end {_key: 'testKey2', _integrationInstanceID: '${testInstanceID}'})
28
- MERGE (start)-[relationship:testRelType]->(end);`
29
+ MERGE (start)-[relationship:testRelType]->(end);`;
29
30
  const wipeByIDCall = `MATCH (n {_integrationInstanceID: '${testInstanceID}'}) DETACH DELETE n`;
30
31
  const wipeAllCall = 'MATCH (n) DETACH DELETE n';
31
- const querySet: QuerySpec[] = [{
32
- name: 'addConstraint',
33
- query: constraintCall,
34
- params: undefined,
35
- output: {records:[]}
36
- },
37
- {
38
- name: 'addEntity',
39
- query: addEntityCall,
40
- params: undefined,
41
- output: {records:[]}
42
- },
43
- {
44
- name: 'addRelationship',
45
- query: addRelationshipCall,
46
- params: undefined,
47
- output: {records:[]}
48
- },
49
- {
50
- name: 'wipeByID',
51
- query: wipeByIDCall,
52
- params: undefined,
53
- output: {records:[]}
54
- },
55
- {
56
- name: 'wipeAll',
57
- query: wipeAllCall,
58
- params: undefined,
59
- output: {records:[]}
60
- }];
32
+ const querySet: QuerySpec[] = [
33
+ {
34
+ name: 'addConstraint',
35
+ query: constraintCall,
36
+ params: undefined,
37
+ output: { records: [] },
38
+ },
39
+ {
40
+ name: 'addEntity',
41
+ query: addEntityCall,
42
+ params: undefined,
43
+ output: { records: [] },
44
+ },
45
+ {
46
+ name: 'addRelationship',
47
+ query: addRelationshipCall,
48
+ params: undefined,
49
+ output: { records: [] },
50
+ },
51
+ {
52
+ name: 'wipeByID',
53
+ query: wipeByIDCall,
54
+ params: undefined,
55
+ output: { records: [] },
56
+ },
57
+ {
58
+ name: 'wipeAll',
59
+ query: wipeAllCall,
60
+ params: undefined,
61
+ output: { records: [] },
62
+ },
63
+ ];
61
64
 
62
65
  describe('#neo4jGraphStore', () => {
63
66
  const mockDriverResp = mockDriver();
@@ -88,12 +91,11 @@ describe('#neo4jGraphStore', () => {
88
91
  });
89
92
 
90
93
  test('should generate call to create a Relationship', () => {
91
-
92
- expect(async () => await store.addRelationships(testRelationshipData)).toReturn;
94
+ expect(async () => await store.addRelationships(testRelationshipData))
95
+ .toReturn;
93
96
  });
94
97
 
95
98
  test('should generate call to wipe by ID', () => {
96
99
  expect(async () => await store.wipeInstanceIdData()).toReturn;
97
100
  });
98
-
99
- });
101
+ });
@@ -1,5 +1,9 @@
1
- import { startsWithNumeric, sanitizePropertyName, sanitizeValue, buildPropertyParameters } from '../neo4jUtilities';
2
-
1
+ import {
2
+ startsWithNumeric,
3
+ sanitizePropertyName,
4
+ sanitizeValue,
5
+ buildPropertyParameters,
6
+ } from '../neo4jUtilities';
3
7
 
4
8
  describe('#neo4jUtilities', () => {
5
9
  test('should return true for string starting with a numeric', () => {
@@ -11,15 +15,29 @@ describe('#neo4jUtilities', () => {
11
15
  expect(testTrailingNumeric).toEqual(false);
12
16
  });
13
17
  test('should sanitize property name properly', () => {
14
- const testSanitize: string = sanitizePropertyName(`1a!b@c#d$e%f^g&h*i(j)k-l=m+n\\o|p'q"r;s:t/u?v.w,x>y<z\`1~2\t3\n4[5]6{7}8 90`);
15
- expect(testSanitize).toEqual('n1a_b_c_d_e_f_g_h_i_j_k_l_m_n_o_p_q_r_s_t_u_v_w_x_y_z_1_2_3_4_5_6_7_8_90');
18
+ const testSanitize: string = sanitizePropertyName(
19
+ `1a!b@c#d$e%f^g&h*i(j)k-l=m+n\\o|p'q"r;s:t/u?v.w,x>y<z\`1~2\t3\n4[5]6{7}8 90`,
20
+ );
21
+ expect(testSanitize).toEqual(
22
+ 'n1a_b_c_d_e_f_g_h_i_j_k_l_m_n_o_p_q_r_s_t_u_v_w_x_y_z_1_2_3_4_5_6_7_8_90',
23
+ );
16
24
  });
17
25
  test('should sanitize value properly', () => {
18
- const testSanitize: string = sanitizeValue('1a!b@c#d$e%f^g&h*i(j)k-l=m+n\\o|p\'q"r;s:t/u?v.w,x>y<z`1~2\t3\n4[5]6{7}8 90');
19
- expect(testSanitize).toEqual('1a!b@c#d$e%f^g&h*i(j)k-l=m+n\\o|p\'q\\"r;s:t/u?v.w,x>y<z`1~2\t3\n4[5]6{7}8 90');
26
+ const testSanitize: string = sanitizeValue(
27
+ '1a!b@c#d$e%f^g&h*i(j)k-l=m+n\\o|p\'q"r;s:t/u?v.w,x>y<z`1~2\t3\n4[5]6{7}8 90',
28
+ );
29
+ expect(testSanitize).toEqual(
30
+ '1a!b@c#d$e%f^g&h*i(j)k-l=m+n\\o|p\'q\\"r;s:t/u?v.w,x>y<z`1~2\t3\n4[5]6{7}8 90',
31
+ );
20
32
  });
21
33
  test('should build property string correctly including sanitization', () => {
22
- const testPropResults: Object = buildPropertyParameters({test: '123', '1sanitize1hi&$abc d': '1h"i&$abc d'});
23
- expect(testPropResults).toEqual({test:'123', n1sanitize1hi__abc_d:'1h\\"i&$abc d'});
34
+ const testPropResults: Object = buildPropertyParameters({
35
+ test: '123',
36
+ '1sanitize1hi&$abc d': '1h"i&$abc d',
37
+ });
38
+ expect(testPropResults).toEqual({
39
+ test: '123',
40
+ n1sanitize1hi__abc_d: '1h\\"i&$abc d',
41
+ });
24
42
  });
25
- });
43
+ });
@@ -1,2 +1,2 @@
1
1
  export * from './uploadToNeo4j';
2
- export * from './wipeNeo4j';
2
+ export * from './wipeNeo4j';