Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
name: Lint and test project
strategy:
matrix:
node: ['18', '20', '24', 'latest']
node: ['24', 'latest']
env:
MAIN_NODE_VER: '24'
steps:
Expand Down Expand Up @@ -88,8 +88,7 @@ jobs:
env:
TRUSTIFY_DA_PYTHON3_PATH: "${{steps.python-location.outputs.python-bin-location}}/python3"
TRUSTIFY_DA_PIP3_PATH: "${{steps.python-location.outputs.python-bin-location}}/pip3"
TRUSTIFY_DA_DEV_MODE: 'true'
DEV_TRUSTIFY_DA_BACKEND_URL: 'https://exhort.stage.devshift.net'
TRUSTIFY_DA_BACKEND_URL: 'https://exhort.stage.devshift.net'
run: npm run test

- name: Compile project
Expand All @@ -98,15 +97,13 @@ jobs:
- name: Run integration tests
run: npm run integration-tests
env:
TRUSTIFY_DA_DEV_MODE: 'true'
DEV_TRUSTIFY_DA_BACKEND_URL: 'https://exhort.stage.devshift.net'
TRUSTIFY_DA_BACKEND_URL: 'https://exhort.stage.devshift.net'

- name: Run integration tests cli
working-directory: integration
run: bash ./run_its.sh
env:
TRUSTIFY_DA_DEV_MODE: 'true'
DEV_TRUSTIFY_DA_BACKEND_URL: 'https://exhort.stage.devshift.net'
TRUSTIFY_DA_BACKEND_URL: 'https://exhort.stage.devshift.net'

- name: Upload coverage reports
if: ${{ matrix.node == env.MAIN_NODE_VER }}
Expand Down
2 changes: 0 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,5 @@ contribution. See the [DCO](DCO) file for details.

<!-- Real links -->
[0]: https://www.conventionalcommits.org/en/v1.0.0/
[1]: https://github.com/guacsec/exhort/blob/0.1.x/src/main/resources/META-INF/openapi.yaml

<!-- Badge links -->
[10]: https://badgen.net/badge/NodeJS%20Version/18/68a063
63 changes: 37 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Exhort JavaScript API<br/>![latest-no-snapshot][0] ![latest-snapshot][1]
# Trustify Dependency Analytics JavaScript Client<br/>![latest-no-snapshot][0] ![latest-snapshot][1]

* Looking for the OpenAPI Spec? Try [Exhort API Spec](https://github.com/trustify-da/trustify-da-api-model)
* Looking for our Java API? Try [Exhort Java API](https://github.com/guacsec/exhort-java-api).
* Looking for our Backend implementation? Try [Exhort](https://github.com/guacsec/exhort).
* Looking for the OpenAPI Spec? Try [Trustify Dependency Analytics API](https://github.com/guacsec/trustify-da-api-spec)
* Looking for our Java API? Try [Trustify Dependency Analytics Java Client](https://github.com/guacsec/trustify-da-java-client).
* Looking for our Backend implementation? Try [Trustify Dependency Analytics](https://github.com/guacsec/trustify-dependency-analytics).

<h3>Usage</h3>
<p>

<strong>Prerequisites:</strong> The <code>TRUSTIFY_DA_BACKEND_URL</code> environment variable must be set to the URL of the Trustify Dependency Analytics backend service. You can set it as an environment variable or pass it in the options object (see <a href="#customization">Customization</a> section).

<ul>
<li>
Use as ESM Module from an ESM module
Expand All @@ -15,24 +17,29 @@ Use as ESM Module from an ESM module
npm install @trustify-da/trustify-da-javascript-client
```

```shell
# Set the mandatory backend URL
export TRUSTIFY_DA_BACKEND_URL=https://trustify-da.example.com
```

```javascript
import exhort from '@trustify-da/trustify-da-javascript-client'
import client from '@trustify-da/trustify-da-javascript-client'
import fs from 'node:fs'

// Get stack analysis in JSON format
let stackAnalysis = await exhort.stackAnalysis('/path/to/pom.xml')
let stackAnalysis = await client.stackAnalysis('/path/to/pom.xml')
// Get stack analysis in HTML format (string)
let stackAnalysisHtml = await exhort.stackAnalysis('/path/to/pom.xml', true)
let stackAnalysisHtml = await client.stackAnalysis('/path/to/pom.xml', true)
// Get component analysis in JSON format
let componentAnalysis = await exhort.componentAnalysis('/path/to/pom.xml')
let componentAnalysis = await client.componentAnalysis('/path/to/pom.xml')
// Get image analysis in JSON format
let imageAnalysis = await exhort.imageAnalysis(['docker.io/library/node:18'])
let imageAnalysis = await client.imageAnalysis(['docker.io/library/node:18'])
// Get image analysis in HTML format (string)
let imageAnalysisHtml = await exhort.imageAnalysis(['docker.io/library/node:18'], true)
let imageAnalysisHtml = await client.imageAnalysis(['docker.io/library/node:18'], true)
// Analyze multiple images
let multipleImagesAnalysis = await exhort.imageAnalysis(['docker.io/library/node:18', 'docker.io/library/python:3.9'])
let multipleImagesAnalysis = await client.imageAnalysis(['docker.io/library/node:18', 'docker.io/library/python:3.9'])
// Specify architecture using ^^ notation (e.g., httpd:2.4.49^^amd64)
let imageAnalysisWithArch = await exhort.imageAnalysis(['httpd:2.4.49^^amd64'])
let imageAnalysisWithArch = await client.imageAnalysis(['httpd:2.4.49^^amd64'])
```
</li>
</ul>
Expand All @@ -45,16 +52,16 @@ npm install @trustify-da/trustify-da-javascript-client
```

```javascript
async function loadExhort()
async function loadTrustifyDa()
{
// dynamic import is the only way to import ESM module into commonJS module
const { default: exhort } = await import('@trustify-da/trustify-da-javascript-client');
return exhort
const { default: client } = await import('@trustify-da/trustify-da-javascript-client');
return client
}
const runExhort = (manifestPath) => {
const runTrustifyDa = (manifestPath) => {
return new Promise(async ( resolve, reject) => {
try {
let stackAnalysisReport = await (await loadExhort()).stackAnalysis(manifestPath,false)
let stackAnalysisReport = await (await loadTrustifyDa()).stackAnalysis(manifestPath,false)
resolve(stackAnalysisReport)

} catch (error)
Expand All @@ -64,7 +71,7 @@ const runExhort = (manifestPath) => {
});
};

runExhort("./path/to/manifest").then(resp => console.log(JSON.stringify(resp,null,4)))
runTrustifyDa("./path/to/manifest").then(resp => console.log(JSON.stringify(resp,null,4)))
```
</li>

Expand Down Expand Up @@ -297,17 +304,21 @@ All of the 5 above examples are valid for marking a package to be ignored

<h3>Customization</h3>
<p>
There are 2 approaches for customizing <em>Exhort JavaScript API</em>. Whether you're using this API as a
There are 2 approaches for customizing <em>Trustify Dependency Analytics JavaScript Client</em>. Whether you're using this API as a
<em>Global Module</em>, a <em>Remote Script</em>, or an <em>ESM Module</em>, you can use <em>Environment Variables</em>
for various customization.

<strong>Note:</strong> The <code>TRUSTIFY_DA_BACKEND_URL</code> environment variable is <strong>mandatory</strong> and must be set to the URL of the Trustify Dependency Analytics backend service. Without this variable, the API will throw an error.

However, <em>ESM Module</em> users, can opt for customizing programmatically:

```javascript
import exhort from '@trustify-da/trustify-da-javascript-client'
import client from '@trustify-da/trustify-da-javascript-client'
import fs from 'node:fs'

let options = {
// Mandatory: Backend URL for Trustify Dependency Analytics service
'TRUSTIFY_DA_BACKEND_URL': 'https://api.trustify.dev',
'TRUSTIFY_DA_MVN_PATH': '/path/to/my/mvn',
'TRUSTIFY_DA_NPM_PATH': '/path/to/npm',
'TRUSTIFY_DA_PNPM_PATH': '/path/to/pnpm',
Expand All @@ -323,19 +334,19 @@ let options = {
}

// Get stack analysis in JSON format ( all package managers, pom.xml is as an example here)
let stackAnalysis = await exhort.stackAnalysis('/path/to/pom.xml', false, options)
let stackAnalysis = await client.stackAnalysis('/path/to/pom.xml', false, options)
// Get stack analysis in HTML format in string ( all package managers, pom.xml is as an example here)
let stackAnalysisHtml = await exhort.stackAnalysis('/path/to/pom.xml', true, options)
let stackAnalysisHtml = await client.stackAnalysis('/path/to/pom.xml', true, options)

// Get component analysis in JSON format
let componentAnalysis = await exhort.componentAnalysis('/path/to/pom.xml', options)
let componentAnalysis = await client.componentAnalysis('/path/to/pom.xml', options)

// Get image analysis in JSON format
let imageAnalysis = await exhort.imageAnalysis(['docker.io/library/node:18'], false, options)
let imageAnalysis = await client.imageAnalysis(['docker.io/library/node:18'], false, options)
// Get image analysis in HTML format in string
let imageAnalysisHtml = await exhort.imageAnalysis(['docker.io/library/node:18'], true, options)
let imageAnalysisHtml = await client.imageAnalysis(['docker.io/library/node:18'], true, options)
// Specify architecture using ^^ notation (e.g., httpd:2.4.49^^amd64)
let imageAnalysisWithArch = await exhort.imageAnalysis(['httpd:2.4.49^^amd64'], false, options)
let imageAnalysisWithArch = await client.imageAnalysis(['httpd:2.4.49^^amd64'], false, options)
```
**_Environment variables takes precedence._**
</p>
Expand Down
8 changes: 4 additions & 4 deletions integration/testers/javascript/index.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
#!/usr/bin/env node

import exhort from '@trustify-da/trustify-da-javascript-client'
import client from '@trustify-da/trustify-da-javascript-client'
import process from 'node:process'

const [,, ...args] = process.argv

if ('stack' === args[0]) {
// arg[1] = manifest path; arg[2] = is html boolean
let html = args[2] === 'true'
let res = await exhort.stackAnalysis(args[1], html)
let res = await client.stackAnalysis(args[1], html)
console.log(html ? res : JSON.stringify(res, null, 2))
process.exit(0)
}
if ('component' === args[0]) {
// arg[1] = manifest path
let res = await exhort.componentAnalysis(args[1])
let res = await client.componentAnalysis(args[1])
console.log(JSON.stringify(res, null, 2))
process.exit(0)
}
Expand All @@ -24,7 +24,7 @@ if ('validateToken' === args[0]) {
let tokens = {
"TRUSTIFY_DA_SNYK_TOKEN" : args[1]
}
let res = await exhort.validateToken(tokens)
let res = await client.validateToken(tokens)
console.log(res)
process.exit(0)
}
Expand Down
12 changes: 6 additions & 6 deletions integration/testers/typescript/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
#!/usr/bin/env node

import exhort from '@guacsec/trustify-da-javascript-client'
import process from 'node:process'
import { AnalysisReport } from '@trustify-da/trustify-da-api-model/model/v5/AnalysisReport'
import client from '@trustify-da/trustify-da-javascript-client';
import process from 'node:process';
import type { AnalysisReport } from '@trustify-da/trustify-da-api-model/model/v5/AnalysisReport';

const [,, ...args] = process.argv
const args = process.argv.slice(2);

if ('stack' === args[0]) {
// arg[1] = manifest path; arg[2] = is html boolean
let html = args[2] === 'true'
let res = await exhort.stackAnalysis(args[1], html)
let res = await client.stackAnalysis(args[1], html)
console.log(html ? res as string : JSON.stringify(res as AnalysisReport, null, 2))
process.exit(0)
}
if ('component' === args[0]) {
// arg[1] = manifest path
let res = await exhort.componentAnalysis(args[1])
let res = await client.componentAnalysis(args[1])
console.log(JSON.stringify(res as AnalysisReport, null, 2))
process.exit(0)
}
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
"exhort",
"secure",
"supply-chain",
"vulnerability"
"vulnerability",
"trustify",
"dependency analytics"
],
"engines": {
"node": ">= 20.0.0",
Expand Down
26 changes: 13 additions & 13 deletions src/analysis.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const rhdaPackageManagerHeader = "rhda-pkg-manager"
/**
* Adds proxy agent configuration to fetch options if a proxy URL is specified
* @param {RequestInit} options - The base fetch options
* @param {import("index.js").Options} opts - The exhort options that may contain proxy configuration
* @param {import("index.js").Options} opts - The trustify DA options that may contain proxy configuration
* @returns {RequestInit} The fetch options with proxy agent if applicable
*/
function addProxyAgent(options, opts) {
Expand Down Expand Up @@ -47,7 +47,7 @@ async function requestStack(provider, manifest, url, html = false, opts = {}) {
let startTime = new Date()
let endTime
if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
console.log("Starting time of sending stack analysis request to exhort server= " + startTime)
console.log("Starting time of sending stack analysis request to the dependency analytics server= " + startTime)
}
opts[rhdaPackageManagerHeader.toUpperCase().replaceAll("-", "_")] = provided.ecosystem

Expand Down Expand Up @@ -80,15 +80,15 @@ async function requestStack(provider, manifest, url, html = false, opts = {}) {
console.log("Unique Identifier associated with this request - ex-request-id=" + exRequestId)
}
endTime = new Date()
console.log("Response body received from exhort server : " + EOL + EOL)
console.log("Response body received from Trustify DA backend server : " + EOL + EOL)
console.log(console.log(JSON.stringify(result, null, 4)))
console.log("Ending time of sending stack analysis request to exhort server= " + endTime)
console.log("Ending time of sending stack analysis request to Trustify DA backend server= " + endTime)
let time = (endTime - startTime) / 1000
console.log("Total Time in seconds: " + time)

}
} else {
throw new Error(`Got error response from exhort backend - http return code : ${resp.status}, error message => ${await resp.text()}`)
throw new Error(`Got error response from Trustify DA backend - http return code : ${resp.status}, error message => ${await resp.text()}`)
}

return Promise.resolve(result)
Expand All @@ -109,7 +109,7 @@ async function requestComponent(provider, manifest, url, opts = {}) {
opts["source-manifest"] = ""
opts[rhdaOperationTypeHeader.toUpperCase().replaceAll("-", "_")] = "component-analysis"
if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
console.log("Starting time of sending component analysis request to exhort server= " + new Date())
console.log("Starting time of sending component analysis request to Trustify DA backend server= " + new Date())
}
opts[rhdaPackageManagerHeader.toUpperCase().replaceAll("-", "_")] = provided.ecosystem

Expand Down Expand Up @@ -137,14 +137,14 @@ async function requestComponent(provider, manifest, url, opts = {}) {
if (exRequestId) {
console.log("Unique Identifier associated with this request - ex-request-id=" + exRequestId)
}
console.log("Response body received from exhort server : " + EOL + EOL)
console.log("Response body received from Trustify DA backend server : " + EOL + EOL)
console.log(JSON.stringify(result, null, 4))
console.log("Ending time of sending component analysis request to exhort server= " + new Date())
console.log("Ending time of sending component analysis request to Trustify DA backend server= " + new Date())


}
} else {
throw new Error(`Got error response from exhort backend - http return code : ${resp.status}, ex-request-id: ${resp.headers.get("ex-request-id")} error message => ${await resp.text()}`)
throw new Error(`Got error response from Trustify DA backend - http return code : ${resp.status}, ex-request-id: ${resp.headers.get("ex-request-id")} error message => ${await resp.text()}`)
}

return Promise.resolve(result)
Expand Down Expand Up @@ -191,13 +191,13 @@ async function requestImages(imageRefs, url, html = false, opts = {}) {
if (exRequestId) {
console.log("Unique Identifier associated with this request - ex-request-id=" + exRequestId)
}
console.log("Response body received from exhort server : " + EOL + EOL)
console.log("Response body received from Trustify DA backend server : " + EOL + EOL)
console.log(JSON.stringify(result, null, 4))
console.log("Ending time of sending component analysis request to exhort server= " + new Date())
console.log("Ending time of sending component analysis request to Trustify DA backend server= " + new Date())
}
return result
} else {
throw new Error(`Got error response from exhort backend - http return code : ${resp.status}, ex-request-id: ${resp.headers.get("ex-request-id")} error message => ${await resp.text()}`)
throw new Error(`Got error response from Trustify DA backend - http return code : ${resp.status}, ex-request-id: ${resp.headers.get("ex-request-id")} error message => ${await resp.text()}`)
}
}

Expand Down Expand Up @@ -264,7 +264,7 @@ function getTokenHeaders(opts = {}) {
setRhdaHeader(rhdaTelemetryId, headers, opts);

if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
console.log("Headers Values to be sent to exhort:" + EOL)
console.log("Headers Values to be sent to Trustify DA backend:" + EOL)
for (const headerKey in headers) {
if (!headerKey.match(RegexNotToBeLogged)) {
console.log(`${headerKey}: ${headers[headerKey]}`)
Expand Down
10 changes: 5 additions & 5 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as path from "path";
import yargs from 'yargs'
import { hideBin } from 'yargs/helpers'

import exhort from './index.js'
import client from './index.js'


// command for component analysis take manifest type and content
Expand All @@ -22,7 +22,7 @@ const component = {
),
handler: async args => {
let manifestName = args['/path/to/manifest']
let res = await exhort.componentAnalysis(manifestName)
let res = await client.componentAnalysis(manifestName)
console.log(JSON.stringify(res, null, 2))
}
}
Expand Down Expand Up @@ -50,7 +50,7 @@ const validateToken = {
let tokenValue = args['tokenValue'].trim()
opts[`TRUSTIFY_DA_${tokenProvider}_TOKEN`] = tokenValue
}
let res = await exhort.validateToken(opts)
let res = await client.validateToken(opts)
console.log(res)
}
}
Expand Down Expand Up @@ -87,7 +87,7 @@ const image = {
}
let html = args['html']
let summary = args['summary']
let res = await exhort.imageAnalysis(imageRefs, html)
let res = await client.imageAnalysis(imageRefs, html)
if(summary && !html) {
let summaries = {}
for (let [imageRef, report] of Object.entries(res)) {
Expand Down Expand Up @@ -144,7 +144,7 @@ const stack = {
let summary = args['summary']
let theProvidersSummary = new Map();
let theProvidersObject ={}
let res = await exhort.stackAnalysis(manifest, html)
let res = await client.stackAnalysis(manifest, html)
if(summary)
{
for (let provider in res.providers ) {
Expand Down
Loading
Loading