diff --git a/CHANGELOG.md b/CHANGELOG.md index c8764dc50..e864bed8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to - Gzip request payloads +- Allow loading modules by name (ex. @jupiterone/graph-rumble) in the + `generate-ingestion-sources-config` and `generate-integration-graph-schema` + commands + ## 11.0.3 - Moved `vis` dependency to devDependencies diff --git a/packages/integration-sdk-cli/src/commands/generate-ingestion-sources-config.ts b/packages/integration-sdk-cli/src/commands/generate-ingestion-sources-config.ts index f2359c617..58b4a364e 100644 --- a/packages/integration-sdk-cli/src/commands/generate-ingestion-sources-config.ts +++ b/packages/integration-sdk-cli/src/commands/generate-ingestion-sources-config.ts @@ -7,7 +7,7 @@ import { StepMetadata, } from '@jupiterone/integration-sdk-core'; import { createCommand } from 'commander'; -import { loadConfigFromTarget } from '../config'; +import { loadConfigFromModule, loadConfigFromTarget } from '../config'; import { promises as fs } from 'fs'; import * as log from '../log'; @@ -26,13 +26,22 @@ export function generateIngestionSourcesConfigCommand() { 'path to integration project directory', process.cwd(), ) + .option( + '-m, --module-name ', + 'name of modules to load (ex "@jupiterone/graph-rumble". Will load using require of package rather than filename)', + ) .action(async (options) => { - const { projectPath, outputFile } = options; + const { projectPath, outputFile, moduleName } = options; log.info( - `Generating ingestion sources config (projectPath=${projectPath}, outputFile=${outputFile})`, + `Generating ingestion sources config (projectPath=${projectPath}, outputFile=${outputFile}, moduleName=${moduleName})`, ); - const config = await loadConfigFromTarget(projectPath); + let config; + if (moduleName) { + config = loadConfigFromModule(moduleName); + } else { + config = await loadConfigFromTarget(projectPath); + } if (!config.ingestionConfig) { log.info( 'Skipping the generation of ingestion sources config file as there is no ingestionConfig present.', diff --git a/packages/integration-sdk-cli/src/commands/generate-integration-graph-schema.ts b/packages/integration-sdk-cli/src/commands/generate-integration-graph-schema.ts index e1ccd630d..52514b964 100644 --- a/packages/integration-sdk-cli/src/commands/generate-integration-graph-schema.ts +++ b/packages/integration-sdk-cli/src/commands/generate-integration-graph-schema.ts @@ -7,7 +7,7 @@ import { StepRelationshipMetadata, } from '@jupiterone/integration-sdk-core'; import { createCommand } from 'commander'; -import { loadConfigFromTarget } from '../config'; +import { loadConfigFromModule, loadConfigFromTarget } from '../config'; import { promises as fs } from 'fs'; import * as log from '../log'; @@ -26,13 +26,22 @@ export function generateIntegrationGraphSchemaCommand() { 'path to integration project directory', process.cwd(), ) + .option( + '-m, --module-name ', + 'name of modules to load (ex "@jupiterone/graph-rumble". Will load using require of package rather than filename)', + ) .action(async (options) => { - const { projectPath, outputFile } = options; + const { projectPath, outputFile, moduleName } = options; log.info( - `Generating integration graph schema (projectPath=${projectPath}, outputFile=${outputFile})`, + `Generating integration graph schema (projectPath=${projectPath}, outputFile=${outputFile}, moduleName=${moduleName})`, ); - const config = await loadConfigFromTarget(projectPath); + let config; + if (moduleName) { + config = loadConfigFromModule(moduleName); + } else { + config = await loadConfigFromTarget(projectPath); + } const integrationGraphSchema = generateIntegrationGraphSchema( config.integrationSteps, diff --git a/packages/integration-sdk-cli/src/config.ts b/packages/integration-sdk-cli/src/config.ts index 97bdc2921..d056d23b4 100644 --- a/packages/integration-sdk-cli/src/config.ts +++ b/packages/integration-sdk-cli/src/config.ts @@ -59,6 +59,21 @@ function loadConfigFromDist(projectPath: string) { return loadConfig(path.join(projectPath, 'dist')); } +export function loadConfigFromModule(mod: string) { + let integrationModule: any; + + try { + integrationModule = require(mod); + } catch (err) { + throw new IntegrationInvocationConfigLoadError( + `Error loading integration invocation configuration. Ensure "invocationConfig" is exported from "${mod}". Additional details: ` + + err, + ); + } + + return integrationModule.invocationConfig as IntegrationInvocationConfig; +} + /** * The way that integration npm packages are distributed has changed over time. * This function handles different cases where the invocation config has