@jupiterone/integration-sdk-cli
Advanced tools
Comparing version 3.2.2 to 3.3.0
@@ -28,3 +28,3 @@ "use strict"; | ||
// coercion function to collect multiple values for a flag | ||
const collecter = (value, arr) => { | ||
const collector = (value, arr) => { | ||
arr.push(...value.split(',')); | ||
@@ -36,7 +36,11 @@ return arr; | ||
.description('Executes the integration and stores the collected data to disk') | ||
.option('-s, --step <steps>', 'step(s) to run, comma separated if multiple', collecter, []) | ||
.option('-s, --step <steps>', 'step(s) to run, comma separated if multiple', collector, []) | ||
.option('-V, --disable-schema-validation', 'Disable schema validation') | ||
.action(async (options) => { | ||
const enableSchemaValidation = !options.disableSchemaValidation; | ||
const config = integration_sdk_runtime_1.prepareLocalStepCollection(await config_1.loadConfig(), options); | ||
log.info('\nConfiguration loaded! Running integration...\n'); | ||
const results = await integration_sdk_runtime_1.executeIntegrationLocally(config); | ||
const results = await integration_sdk_runtime_1.executeIntegrationLocally(config, { | ||
enableSchemaValidation, | ||
}); | ||
log.displayExecutionResults(results); | ||
@@ -43,0 +47,0 @@ }); |
@@ -1,4 +0,4 @@ | ||
import { Node, Edge } from "vis"; | ||
import { Entity, MappedRelationship, RelationshipDirection, RelationshipMapping } from "@jupiterone/integration-sdk-core"; | ||
import { NodeEntity } from "./utils"; | ||
import { Node, Edge } from 'vis'; | ||
import { Entity, MappedRelationship, RelationshipDirection, RelationshipMapping } from '@jupiterone/integration-sdk-core'; | ||
import { NodeEntity } from './utils'; | ||
interface MappedRelationshipNodesAndEdges { | ||
@@ -5,0 +5,0 @@ mappedRelationshipNodes: Node[]; |
@@ -29,3 +29,4 @@ "use strict"; | ||
const { _class: targetEntityClass, ...targetEntityRest } = targetEntity; | ||
return lodash_1.isMatch(entityRest, targetEntityRest) && isClassMatch(entityClass, targetEntityClass); | ||
return (lodash_1.isMatch(entityRest, targetEntityRest) && | ||
isClassMatch(entityClass, targetEntityClass)); | ||
}); | ||
@@ -55,3 +56,2 @@ if (matchedEntity !== undefined) | ||
} | ||
; | ||
function findOrCreatePlaceholderEntity(nodeEntities, _mapping) { | ||
@@ -70,10 +70,12 @@ const targetEntity = findTargetEntity(nodeEntities, _mapping); | ||
const mappedRelationshipEdges = []; | ||
const explicitNodeEntities = [...explicitEntities.map((e) => ({ ...e, nodeId: utils_1.getNodeIdFromEntity(e, []) }))]; | ||
const explicitNodeEntities = [ | ||
...explicitEntities.map((e) => ({ | ||
...e, | ||
nodeId: utils_1.getNodeIdFromEntity(e, []), | ||
})), | ||
]; | ||
const missingNodeEntities = []; | ||
const placeholderNodeEntities = []; | ||
for (const mappedRelationship of mappedRelationships) { | ||
const sourceEntity = findOrCreateSourceEntity([ | ||
...explicitNodeEntities, | ||
...missingNodeEntities | ||
], mappedRelationship._mapping.sourceEntityKey); | ||
const sourceEntity = findOrCreateSourceEntity([...explicitNodeEntities, ...missingNodeEntities], mappedRelationship._mapping.sourceEntityKey); | ||
let sourceNodeId; | ||
@@ -86,3 +88,3 @@ if (isNewMissingEntity(sourceEntity)) { | ||
...missingNodeEntities, | ||
...placeholderNodeEntities | ||
...placeholderNodeEntities, | ||
]), | ||
@@ -99,3 +101,3 @@ }; | ||
...missingNodeEntities, | ||
...placeholderNodeEntities | ||
...placeholderNodeEntities, | ||
]); | ||
@@ -106,3 +108,3 @@ } | ||
...missingNodeEntities, | ||
...placeholderNodeEntities | ||
...placeholderNodeEntities, | ||
], mappedRelationship._mapping); | ||
@@ -116,3 +118,3 @@ let targetNodeId; | ||
...missingNodeEntities, | ||
...placeholderNodeEntities | ||
...placeholderNodeEntities, | ||
]), | ||
@@ -129,3 +131,3 @@ }; | ||
...missingNodeEntities, | ||
...placeholderNodeEntities | ||
...placeholderNodeEntities, | ||
]); | ||
@@ -185,3 +187,6 @@ } | ||
function getWrappedEntityPropertiesString(nodeEntity) { | ||
return getWrappedJsonString({ JSONableObject: nodeEntity, keysToOmit: ['nodeId'] }); | ||
return getWrappedJsonString({ | ||
JSONableObject: nodeEntity, | ||
keysToOmit: ['nodeId'], | ||
}); | ||
} | ||
@@ -188,0 +193,0 @@ function createPlaceholderEntityNode(targetEntity) { |
{ | ||
"name": "@jupiterone/integration-sdk-cli", | ||
"version": "3.2.2", | ||
"version": "3.3.0", | ||
"description": "The SDK for developing JupiterOne integrations", | ||
@@ -25,3 +25,3 @@ "main": "dist/src/index.js", | ||
"dependencies": { | ||
"@jupiterone/integration-sdk-runtime": "^3.2.2", | ||
"@jupiterone/integration-sdk-runtime": "^3.3.0", | ||
"commander": "^5.0.0", | ||
@@ -35,3 +35,3 @@ "globby": "^11.0.0", | ||
"devDependencies": { | ||
"@jupiterone/integration-sdk-private-test-utils": "^3.2.2", | ||
"@jupiterone/integration-sdk-private-test-utils": "^3.3.0", | ||
"@pollyjs/adapter-node-http": "^4.0.4", | ||
@@ -49,3 +49,3 @@ "@pollyjs/core": "^4.0.4", | ||
}, | ||
"gitHead": "1b7af1e12957e47d52795791b25cd246aa34af8a" | ||
"gitHead": "07a959556ad0c9db4dee7718dffc4472de0ee098" | ||
} |
@@ -88,2 +88,58 @@ import path from 'path'; | ||
describe('schema validation', () => { | ||
beforeEach(() => { | ||
loadProjectStructure('instanceWithNonValidatingSteps'); | ||
delete process.env.ENABLE_GRAPH_OBJECT_SCHEMA_VALIDATION; | ||
}); | ||
test('step should fail if enableSchemaValidation = true', async () => { | ||
await createCli().parseAsync(['node', 'j1-integration', 'collect']); | ||
expect(log.displayExecutionResults).toHaveBeenCalledTimes(1); | ||
expect(log.displayExecutionResults).toHaveBeenCalledWith({ | ||
integrationStepResults: [ | ||
{ | ||
id: 'fetch-users', | ||
name: 'Fetch Users', | ||
declaredTypes: ['my_user'], | ||
encounteredTypes: [], | ||
status: StepResultStatus.FAILURE, | ||
}, | ||
], | ||
metadata: { | ||
partialDatasets: { | ||
types: ['my_user'], | ||
}, | ||
}, | ||
}); | ||
}); | ||
test('step should pass if enableSchemaValidation = false', async () => { | ||
await createCli().parseAsync([ | ||
'node', | ||
'j1-integration', | ||
'collect', | ||
'--disable-schema-validation', | ||
]); | ||
expect(log.displayExecutionResults).toHaveBeenCalledTimes(1); | ||
expect(log.displayExecutionResults).toHaveBeenCalledWith({ | ||
integrationStepResults: [ | ||
{ | ||
id: 'fetch-users', | ||
name: 'Fetch Users', | ||
declaredTypes: ['my_user'], | ||
encounteredTypes: ['my_user'], | ||
status: StepResultStatus.SUCCESS, | ||
}, | ||
], | ||
metadata: { | ||
partialDatasets: { | ||
types: [], | ||
}, | ||
}, | ||
}); | ||
}); | ||
}); | ||
describe('-s or --step option', () => { | ||
@@ -90,0 +146,0 @@ test('will only run the steps provided if the -s / --steps option is passed in', async () => { |
@@ -12,3 +12,3 @@ import { createCommand } from 'commander'; | ||
// coercion function to collect multiple values for a flag | ||
const collecter = (value: string, arr: string[]) => { | ||
const collector = (value: string, arr: string[]) => { | ||
arr.push(...value.split(',')); | ||
@@ -26,11 +26,15 @@ return arr; | ||
'step(s) to run, comma separated if multiple', | ||
collecter, | ||
collector, | ||
[], | ||
) | ||
.option('-V, --disable-schema-validation', 'Disable schema validation') | ||
.action(async (options) => { | ||
const enableSchemaValidation = !options.disableSchemaValidation; | ||
const config = prepareLocalStepCollection(await loadConfig(), options); | ||
log.info('\nConfiguration loaded! Running integration...\n'); | ||
const results = await executeIntegrationLocally(config); | ||
const results = await executeIntegrationLocally(config, { | ||
enableSchemaValidation, | ||
}); | ||
log.displayExecutionResults(results); | ||
}); | ||
} |
@@ -1,3 +0,3 @@ | ||
import { Node, Edge, NodeOptions } from "vis"; | ||
import { | ||
import { Node, Edge, NodeOptions } from 'vis'; | ||
import { | ||
Entity, | ||
@@ -8,5 +8,5 @@ MappedRelationship, | ||
TargetEntityProperties, | ||
} from "@jupiterone/integration-sdk-core"; | ||
import { isMatch, pick } from "lodash"; | ||
import { getNodeIdFromEntity, NodeEntity, isNodeIdDuplicate } from "./utils"; | ||
} from '@jupiterone/integration-sdk-core'; | ||
import { isMatch, pick } from 'lodash'; | ||
import { getNodeIdFromEntity, NodeEntity, isNodeIdDuplicate } from './utils'; | ||
@@ -18,3 +18,6 @@ interface MappedRelationshipNodesAndEdges { | ||
export function isClassMatch(entityClasses: string | string[] | undefined, targetEntityClasses: string | string[] | undefined): boolean { | ||
export function isClassMatch( | ||
entityClasses: string | string[] | undefined, | ||
targetEntityClasses: string | string[] | undefined, | ||
): boolean { | ||
if (targetEntityClasses === undefined) { | ||
@@ -32,6 +35,11 @@ return true; | ||
return targetEntityClasses.every((targetClass) => (entityClasses as string[]).includes(targetClass)); | ||
return targetEntityClasses.every((targetClass) => | ||
(entityClasses as string[]).includes(targetClass), | ||
); | ||
} | ||
export function findTargetEntity(entities: NodeEntity[], _mapping: RelationshipMapping): NodeEntity | undefined { | ||
export function findTargetEntity( | ||
entities: NodeEntity[], | ||
_mapping: RelationshipMapping, | ||
): NodeEntity | undefined { | ||
for (const targetFilterKey of _mapping.targetFilterKeys) { | ||
@@ -44,3 +52,9 @@ const targetEntity = pick(_mapping.targetEntity, targetFilterKey); | ||
return isMatch(entityRest, targetEntityRest) && isClassMatch(entityClass, (targetEntityClass as string | string[] | undefined)); | ||
return ( | ||
isMatch(entityRest, targetEntityRest) && | ||
isClassMatch( | ||
entityClass, | ||
targetEntityClass as string | string[] | undefined, | ||
) | ||
); | ||
}); | ||
@@ -54,7 +68,12 @@ | ||
function isNewMissingEntity(sourceEntity: NodeEntity | NewMissingEntity): sourceEntity is NewMissingEntity { | ||
function isNewMissingEntity( | ||
sourceEntity: NodeEntity | NewMissingEntity, | ||
): sourceEntity is NewMissingEntity { | ||
return (sourceEntity as any).nodeId === undefined; | ||
} | ||
function findOrCreateSourceEntity(explicitEntities: NodeEntity[], sourceEntityKey: string): NodeEntity | NewMissingEntity { | ||
function findOrCreateSourceEntity( | ||
explicitEntities: NodeEntity[], | ||
sourceEntityKey: string, | ||
): NodeEntity | NewMissingEntity { | ||
const sourceEntity = explicitEntities.find((e) => e._key === sourceEntityKey); | ||
@@ -73,7 +92,12 @@ if (sourceEntity === undefined) { | ||
function isNewPlaceholderEntity(targetEntity: NodeEntity | NewPlaceholderEntity): targetEntity is NewPlaceholderEntity { | ||
function isNewPlaceholderEntity( | ||
targetEntity: NodeEntity | NewPlaceholderEntity, | ||
): targetEntity is NewPlaceholderEntity { | ||
return (targetEntity as any).nodeId === undefined; | ||
}; | ||
} | ||
function findOrCreatePlaceholderEntity(nodeEntities: NodeEntity[], _mapping: RelationshipMapping): Entity | NewPlaceholderEntity { | ||
function findOrCreatePlaceholderEntity( | ||
nodeEntities: NodeEntity[], | ||
_mapping: RelationshipMapping, | ||
): NodeEntity | NewPlaceholderEntity { | ||
const targetEntity = findTargetEntity(nodeEntities, _mapping); | ||
@@ -88,4 +112,4 @@ if (targetEntity === undefined) { | ||
export function createMappedRelationshipNodesAndEdges(options: { | ||
mappedRelationships: MappedRelationship[], | ||
explicitEntities: Entity[], | ||
mappedRelationships: MappedRelationship[]; | ||
explicitEntities: Entity[]; | ||
}): MappedRelationshipNodesAndEdges { | ||
@@ -96,3 +120,8 @@ const { mappedRelationships, explicitEntities } = options; | ||
const explicitNodeEntities: NodeEntity[] = [...explicitEntities.map((e) => ({ ...e, nodeId: getNodeIdFromEntity(e, [])}))]; | ||
const explicitNodeEntities: NodeEntity[] = [ | ||
...explicitEntities.map((e) => ({ | ||
...e, | ||
nodeId: getNodeIdFromEntity(e, []), | ||
})), | ||
]; | ||
const missingNodeEntities: NodeEntity[] = []; | ||
@@ -102,6 +131,6 @@ const placeholderNodeEntities: NodeEntity[] = []; | ||
for (const mappedRelationship of mappedRelationships) { | ||
const sourceEntity = findOrCreateSourceEntity([ | ||
...explicitNodeEntities, | ||
...missingNodeEntities | ||
], mappedRelationship._mapping.sourceEntityKey); | ||
const sourceEntity = findOrCreateSourceEntity( | ||
[...explicitNodeEntities, ...missingNodeEntities], | ||
mappedRelationship._mapping.sourceEntityKey, | ||
); | ||
let sourceNodeId: string; | ||
@@ -112,9 +141,9 @@ if (isNewMissingEntity(sourceEntity)) { | ||
nodeId: getNodeIdFromEntity(sourceEntity, [ | ||
...explicitNodeEntities, | ||
...missingNodeEntities, | ||
...placeholderNodeEntities | ||
...explicitNodeEntities, | ||
...missingNodeEntities, | ||
...placeholderNodeEntities, | ||
]), | ||
}; | ||
missingNodeEntities.push(missingSourceEntity); | ||
const sourceNode = createMissingEntityNode(missingSourceEntity); | ||
@@ -125,13 +154,16 @@ mappedRelationshipNodes.push(sourceNode); | ||
sourceNodeId = getNodeIdFromEntity(sourceEntity, [ | ||
...explicitNodeEntities, | ||
...missingNodeEntities, | ||
...placeholderNodeEntities | ||
...explicitNodeEntities, | ||
...missingNodeEntities, | ||
...placeholderNodeEntities, | ||
]); | ||
} | ||
const targetEntity = findOrCreatePlaceholderEntity([ | ||
...explicitNodeEntities, | ||
...missingNodeEntities, | ||
...placeholderNodeEntities | ||
], mappedRelationship._mapping); | ||
const targetEntity = findOrCreatePlaceholderEntity( | ||
[ | ||
...explicitNodeEntities, | ||
...missingNodeEntities, | ||
...placeholderNodeEntities, | ||
], | ||
mappedRelationship._mapping, | ||
); | ||
let targetNodeId: string; | ||
@@ -142,5 +174,5 @@ if (isNewPlaceholderEntity(targetEntity)) { | ||
nodeId: getNodeIdFromEntity(targetEntity, [ | ||
...explicitNodeEntities, | ||
...missingNodeEntities, | ||
...placeholderNodeEntities | ||
...explicitNodeEntities, | ||
...missingNodeEntities, | ||
...placeholderNodeEntities, | ||
]), | ||
@@ -155,9 +187,16 @@ }; | ||
targetNodeId = getNodeIdFromEntity(targetEntity, [ | ||
...explicitNodeEntities, | ||
...missingNodeEntities, | ||
...placeholderNodeEntities | ||
...explicitNodeEntities, | ||
...missingNodeEntities, | ||
...placeholderNodeEntities, | ||
]); | ||
} | ||
mappedRelationshipEdges.push(createMappedRelationshipEdge(sourceNodeId, targetNodeId, mappedRelationship.displayName, mappedRelationship._mapping.relationshipDirection)) | ||
mappedRelationshipEdges.push( | ||
createMappedRelationshipEdge( | ||
sourceNodeId, | ||
targetNodeId, | ||
mappedRelationship.displayName, | ||
mappedRelationship._mapping.relationshipDirection, | ||
), | ||
); | ||
} | ||
@@ -168,12 +207,12 @@ | ||
mappedRelationshipEdges, | ||
} | ||
}; | ||
} | ||
function createEntityNode( | ||
node: Node, | ||
node: Node, | ||
options: { | ||
isDuplicateId?: boolean, | ||
labelHeader?: string, | ||
labelBody?: string, | ||
} | ||
isDuplicateId?: boolean; | ||
labelHeader?: string; | ||
labelBody?: string; | ||
}, | ||
): Node { | ||
@@ -202,3 +241,3 @@ const overrides: Partial<NodeOptions> = {}; | ||
{ | ||
id:sourceEntity.nodeId, | ||
id: sourceEntity.nodeId, | ||
color: 'red', | ||
@@ -218,6 +257,9 @@ group: MISSING_GROUP, | ||
/** | ||
* | ||
* @param JSONableObject | ||
* | ||
* @param JSONableObject | ||
*/ | ||
function getWrappedJsonString(options: {JSONableObject: object, keysToOmit: string[]}): string { | ||
function getWrappedJsonString(options: { | ||
JSONableObject: object; | ||
keysToOmit: string[]; | ||
}): string { | ||
const { JSONableObject, keysToOmit } = options; | ||
@@ -234,3 +276,6 @@ const keyValueArray: string[] = []; | ||
function getWrappedEntityPropertiesString(nodeEntity: NodeEntity): string { | ||
return getWrappedJsonString({JSONableObject: nodeEntity, keysToOmit: ['nodeId']}) | ||
return getWrappedJsonString({ | ||
JSONableObject: nodeEntity, | ||
keysToOmit: ['nodeId'], | ||
}); | ||
} | ||
@@ -252,3 +297,8 @@ | ||
export function createMappedRelationshipEdge(sourceNodeId: string, targetNodeId: string, label: string | undefined, relationshipDirection: RelationshipDirection): Edge { | ||
export function createMappedRelationshipEdge( | ||
sourceNodeId: string, | ||
targetNodeId: string, | ||
label: string | undefined, | ||
relationshipDirection: RelationshipDirection, | ||
): Edge { | ||
let fromKey: string; | ||
@@ -272,3 +322,3 @@ let toKey: string; | ||
dashes: true, | ||
} | ||
}; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
533789
4020