Skip to content

Commit

Permalink
fix: fix foundry-js typos on docs
Browse files Browse the repository at this point in the history
  • Loading branch information
rlucha-crowdstrike committed Oct 24, 2024
1 parent ff7e8d4 commit b2494b2
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 88 deletions.
186 changes: 99 additions & 87 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# @crowdstrike/foundry-js

`foundry.js` javascript library provides convenient access to the CrowdStrike's Foundry API to author UI pages and extensions.
`foundry-js` javascript library provides convenient access to the CrowdStrike's Foundry API to author UI pages and extensions.

### Installation

Expand All @@ -25,95 +25,106 @@ When application starts, it should establish connection to Falcon Console. If co
```javascript
import FalconApi from '@crowdstrike/foundry-js';

(async () => {
async () => {
const falcon = new FalconApi();

await falcon.connect();
});
};
```

### Receive events from Falcon Console

When UI extensions is loaded, it might receive data for the context it is loaded,
When UI extensions is loaded, it might receive data for the context it is loaded,
for example if UI extension was built for Detection side panel, it will receive detection associated data.
If `data` is updated in Falcon Console - event will automatically execute and pass new data.

```javascript
(async () => {
async () => {
falcon.events.on('data', (data) => {
// store received `data` and use it inside your application
});
});
};
```

### Working with Workflows

To call on-demand workflow:

```javascript
(async () => {
async () => {
const config = { name: 'WorkflowName', depth: 0 };

const pendingResult = await falcon.api.workflows.postEntitiesExecuteV1({}, config);
const pendingResult = await falcon.api.workflows.postEntitiesExecuteV1(
{},
config,
);

const result = await falcon.api.workflows.getEntitiesExecutionResultsV1({ ids: triggerResult.resources[0] });
});
const result = await falcon.api.workflows.getEntitiesExecutionResultsV1({
ids: triggerResult.resources[0],
});
};
```

### Working with Collections

```javascript
(async () => {
async () => {
const sampleData = {
"name": "John",
"age": 42,
"aliases": ["Doe", "Foundry"]
name: 'John',
age: 42,
aliases: ['Doe', 'Foundry'],
};

const collection = falcon
.collection({collection: '<collectionName>' });

const collection = falcon.collection({ collection: '<collectionName>' });

// to write a collection
const result = await collection.write('test-key', sampleData);

// read collection
const record = await collection.read('test-key');
// record.age === 42

// search collection, `filter` uses FQL (Falcon Query Language)
const searchResult = await collection.search({ filter: `name:'*'` });

// deletes record
const deleteResponse = await collection.delete('test-key');
});
};
```

### Working with LogScale

```javascript
(async () => {
async () => {
// write to LogScale
const writeResult = await falcon.logscale.write({ test: 'check' });
// writeResult.resources?.[0]?.rows_written === 1

// run dynamic query
const queryResult = await falcon.logscale.query({ search_query: "*", start: "1h" });
const queryResult = await falcon.logscale.query({
search_query: '*',
start: '1h',
});
// queryResult.resources?.[0]?.event_count > 0

// run saved query
const savedQueryResult = await falcon.logscale.savedQuery({ id: "<savedQueryId>", start: "30d", mode: 'sync' });
const savedQueryResult = await falcon.logscale.savedQuery({
id: '<savedQueryId>',
start: '30d',
mode: 'sync',
});
// savedQueryResult.resources?.[0]?.event_count > 0
});
};
```

### Working with API Integration

To call API Integration, App should be initially provisioned, and configuration for API Integration should be set up.
To call API Integration, App should be initially provisioned, and configuration for API Integration should be set up.

```javascript
(async () => {
async () => {
// we assume, that API Integration was created and operation Get Cities exists

const apiIntegration = falcon.apiIntegration({
definitionId: '<api-integration-id from manifest.yml>',
operationId: 'Get Cities',
Expand All @@ -123,79 +134,82 @@ To call API Integration, App should be initially provisioned, and configuration
request: {
params: {
path: {
country: 'Spain'
}
}
}
country: 'Spain',
},
},
},
});
// response.resources?.[0]?.status_code === 200
// date is at response.resources[0].response_body
});
};
```

### Working with Cloud Functions

```javascript
(async () => {
async () => {
const config = {
name: 'CloudFunctionName',
version: 1
version: 1,
};

const cloudFunction = falcon.cloudFunction(config);

// you can specify path parameters that will be passsed to your Cloud Function.
// `id` and `mode` - example query params that your Cloud Function will receive
const getResponse = await cloudFunction.path('/?id=150&mode=compact')
.get();

// you can call different HTTP methods - GET, POST, PATCH, PUT, DELETE
const postResponse = await cloudFunction.path('/')
.post({ name: 'test' });

const patchResponse = cloudFunction.path('/')
.patch({ name: 'test' });

const putResponse = cloudFunction.path('/')
.put({ name: 'test' });

const deleteResponse = cloudFunction.path('/?id=100')
.delete();
});
// you can specify path parameters that will be passsed to your Cloud Function.
// `id` and `mode` - example query params that your Cloud Function will receive
const getResponse = await cloudFunction.path('/?id=150&mode=compact').get();

// you can call different HTTP methods - GET, POST, PATCH, PUT, DELETE
const postResponse = await cloudFunction.path('/').post({ name: 'test' });

const patchResponse = cloudFunction.path('/').patch({ name: 'test' });

const putResponse = cloudFunction.path('/').put({ name: 'test' });

const deleteResponse = cloudFunction.path('/?id=100').delete();
};
```

### Navigation utilities

As Page or UI extension will run inside sandboxed iframe, clicking links or navigating will be limited.
When browser URL changes, Foundry UI Page will receive that data via iframe hash change event.
You can listen to hash change event and process your app internal navigation.
You can listen to hash change event and process your app internal navigation.

```javascript
window.addEventListener("hashchange", (event) => {
let rawHash = new URL(event.newURL).hash;
window.addEventListener(
'hashchange',
(event) => {
let rawHash = new URL(event.newURL).hash;

const path = rawHash.substring(1);
}, false);
const path = rawHash.substring(1);
},
false,
);

// to read initial hash when your app loads:
const initialPath = document.location.hash.substring(1);
```

If you have links in your application, that point to the internal URLs of your application (for example navigation from /page-1 to /page-2) -
If you have links in your application, that point to the internal URLs of your application (for example navigation from /page-1 to /page-2) -
you can add `data-` attribute to those links, and add onClick handler, that will handle navigation outside of iframe and will update iframe hash.

```javascript
// find all links with data attribute - `data-internal-link`
document.querySelector('[data-internal-link]')
.addEventListener('click', (event) => falcon.navigation.onClick(event, '_self', 'internal'));
// find all links with data attribute - `data-internal-link`
document
.querySelector('[data-internal-link]')
.addEventListener('click', (event) =>
falcon.navigation.onClick(event, '_self', 'internal'),
);
```

If you have external links that you want to navigate to, for example www.crowdstrike.com, you can add `data-` attribute to identify those:

```javascript
// find all links with data attribute - `data-external-link`
document.querySelector('[data-external-link]')
.addEventListener('click', (event) => falcon.navigation.onClick(event));
// find all links with data attribute - `data-external-link`
document
.querySelector('[data-external-link]')
.addEventListener('click', (event) => falcon.navigation.onClick(event));
```

### Modal utility
Expand All @@ -204,39 +218,37 @@ To open a modal within Falcon Console, rendering UI extension of your choice:

```javascript
const result = await api.ui.openModal(
{
id: '<extension ID as defined in the manifest>',
type: 'extension' // 'extension' | 'page'
{
id: '<extension ID as defined in the manifest>',
type: 'extension', // 'extension' | 'page'
},
'Modal title',
'Modal title',
{
path: '/', // initial path that will be set when page or extension loads
path: '/', // initial path that will be set when page or extension loads
data: { foo: 'bar' }, // data to pass to the modal
size: 'lg', // width of the modal - 'sm', 'md', 'lg', 'xl'. 'md' is default
align: 'top', // vertical alignment - 'top' or undefined
} // OpenModalOptions
}, // OpenModalOptions
);

// to close modal:
await api.ui.closeModal();

await api.ui.closeModal({ foo: 'bar' });// you can pass payload
await api.ui.closeModal({ foo: 'bar' }); // you can pass payload
```

## Sample apps

| Application | Framework |
|------------------------------------------------------------------------------------|-----------|
| [ Triage with MITRE Attack ](https://github.com/CrowdStrike/foundry-sample-mitre ) | Vue |
| [ Scalable RTR ]( https://github.com/CrowdStrike/foundry-sample-scalable-rtr ) | React |
| [ Rapid Response ]( https://github.com/CrowdStrike/foundry-sample-rapid-response ) | React |
| Application | Framework |
| --------------------------------------------------------------------------------- | --------- |
| [ Triage with MITRE Attack ](https://github.com/CrowdStrike/foundry-sample-mitre) | Vue |
| [ Scalable RTR ](https://github.com/CrowdStrike/foundry-sample-scalable-rtr) | React |
| [ Rapid Response ](https://github.com/CrowdStrike/foundry-sample-rapid-response) | React |

## Additionally

| | Description |
|-------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------|
| [ Javascript Blueprint ](https://github.com/CrowdStrike/foundry-js-blueprint-javascript ) | Starter Javascript blueprint used in Foundry CLI |
| [ React Blueprint ]( https://github.com/CrowdStrike/foundry-js-blueprint-react ) | Starter React blueprint used in Foundry CLI |
| [Falcon Shoelace](https://github.com/CrowdStrike/falcon-shoelace) | [Shoelace Library](https://shoelace.style/) of web components styled to fit in Falcon Console |


| | Description |
| ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| [ Javascript Blueprint ](https://github.com/CrowdStrike/foundry-js-blueprint-javascript) | Starter Javascript blueprint used in Foundry CLI |
| [ React Blueprint ](https://github.com/CrowdStrike/foundry-js-blueprint-react) | Starter React blueprint used in Foundry CLI |
| [Falcon Shoelace](https://github.com/CrowdStrike/falcon-shoelace) | [Shoelace Library](https://shoelace.style/) of web components styled to fit in Falcon Console |
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@crowdstrike/foundry-js",
"version": "0.16.0",
"description": "foundry.js is the JavaScript SDK for authoring UI Extensions for CrowdStrike's Foundry platform.",
"description": "foundry-js is the JavaScript SDK for authoring UI Extensions for CrowdStrike's Foundry platform.",
"repository": {
"type": "git",
"url": "https://github.com/CrowdStrike/foundry-js.git"
Expand Down

0 comments on commit b2494b2

Please sign in to comment.