Skip to content

Commit

Permalink
New cli command tr-pull-datapoints (#365)
Browse files Browse the repository at this point in the history
* Export datpaoints

* ud

* ud

* ud

* ud

* ud
  • Loading branch information
michaelfarrell76 authored Nov 22, 2024
1 parent 145c8d5 commit 4eafcf0
Show file tree
Hide file tree
Showing 18 changed files with 813 additions and 51 deletions.
10 changes: 5 additions & 5 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
85 changes: 79 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,30 +114,34 @@
- [Authentication](#authentication-25)
- [Arguments](#arguments-25)
- [Usage](#usage-26)
- [tr-upload-consent-preferences](#tr-upload-consent-preferences)
- [tr-pull-datapoints](#tr-pull-datapoints)
- [Authentication](#authentication-26)
- [Arguments](#arguments-26)
- [Usage](#usage-27)
- [tr-pull-consent-preferences](#tr-pull-consent-preferences)
- [tr-upload-consent-preferences](#tr-upload-consent-preferences)
- [Authentication](#authentication-27)
- [Arguments](#arguments-27)
- [Usage](#usage-28)
- [tr-upload-data-flows-from-csv](#tr-upload-data-flows-from-csv)
- [tr-pull-consent-preferences](#tr-pull-consent-preferences)
- [Authentication](#authentication-28)
- [Arguments](#arguments-28)
- [Usage](#usage-29)
- [tr-upload-cookies-from-csv](#tr-upload-cookies-from-csv)
- [tr-upload-data-flows-from-csv](#tr-upload-data-flows-from-csv)
- [Authentication](#authentication-29)
- [Arguments](#arguments-29)
- [Usage](#usage-30)
- [tr-generate-api-keys](#tr-generate-api-keys)
- [tr-upload-cookies-from-csv](#tr-upload-cookies-from-csv)
- [Authentication](#authentication-30)
- [Arguments](#arguments-30)
- [Usage](#usage-31)
- [tr-build-xdi-sync-endpoint](#tr-build-xdi-sync-endpoint)
- [tr-generate-api-keys](#tr-generate-api-keys)
- [Authentication](#authentication-31)
- [Arguments](#arguments-31)
- [Usage](#usage-32)
- [tr-build-xdi-sync-endpoint](#tr-build-xdi-sync-endpoint)
- [Authentication](#authentication-32)
- [Arguments](#arguments-32)
- [Usage](#usage-33)
- [Prompt Manager](#prompt-manager)
- [Proxy usage](#proxy-usage)

Expand Down Expand Up @@ -2209,6 +2213,75 @@ Bin data hourly vs daily
yarn tr-pull-consent-metrics --auth=$TRANSCEND_API_KEY --start=01/01/2023 --bin=1h
```

### tr-pull-datapoints

This command allows for pulling your Data Inventory -> Datapoints into a CSV.

#### Authentication

In order to use this cli, you will first need to generate an API key on the Transcend Admin Dashboard (https://app.transcend.io/infrastructure/api-keys).

The API key must have the following scopes:

- "View Data Inventory"

#### Arguments

| Argument | Description | Type | Default | Required |
| ------------------------ | ----------------------------------------------------------------------------- | ------------- | ------------------------ | -------- |
| auth | The Transcend API key with the scopes necessary for the command. | string | N/A | true |
| file | The file to save datapoints to | string - path | ./datapoints.csv | false |
| transcendUrl | URL of the Transcend backend. Use https://api.us.transcend.io for US hosting. | string - URL | https://api.transcend.io | false |
| dataSiloIds | Comma-separated list of data silo IDs to filter by | string | N/A | false |
| includeAttributes | Whether to include attributes in the output | boolean | false | false |
| includeGuessedCategories | Whether to include guessed categories in the output | boolean | false | false |
| parentCategories | Comma-separated list of parent categories to filter by | string | N/A | false |
| subCategories | Comma-separated list of subcategories to filter by | string | N/A | false |

#### Usage

All arguments

```sh
yarn tr-pull-datapoints --auth=$TRANSCEND_API_KEY --file=./datapoints.csv --includeGuessedCategories=true --parentCategories=CONTACT,ID,LOCATION --subCategories=79d998b7-45dd-481c-ae3a-856fd93458b2,9ecc213a-cd46-46d6-afd9-46cea713f5d1 --dataSiloIds=f956ccce-5534-4328-a78d-3a924b1fe429
```

Pull datapoints for specific data silos:

```sh
yarn tr-pull-datapoints --auth=$TRANSCEND_API_KEY --file=./datapoints.csv --dataSiloIds=f956ccce-5534-4328-a78d-3a924b1fe429
```

Include attributes in the output:

```sh
yarn tr-pull-datapoints --auth=$TRANSCEND_API_KEY --file=./datapoints.csv --includeAttributes=true
```

Include guessed categories in the output:

```sh
yarn tr-pull-datapoints --auth=$TRANSCEND_API_KEY --file=./datapoints.csv --includeGuessedCategories=true
```

Filter by parent categories:

```sh
yarn tr-pull-datapoints --auth=$TRANSCEND_API_KEY --file=./datapoints.csv --parentCategories=ID,LOCATION
```

Filter by subcategories:

```sh
yarn tr-pull-datapoints --auth=$TRANSCEND_API_KEY --file=./datapoints.csv --subCategories=79d998b7-45dd-481c-ae3a-856fd93458b2,9ecc213a-cd46-46d6-afd9-46cea713f5d1
```

Specify the backend URL, needed for US hosted backend infrastructure:

```sh
yarn tr-pull-datapoints --auth=$TRANSCEND_API_KEY --file=./datapoints.csv --transcendUrl=https://api.us.transcend.io
```

### tr-upload-consent-preferences

This command allows for updating of consent preferences to the [Managed Consent Database](https://docs.transcend.io/docs/consent/reference/managed-consent-database).
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"author": "Transcend Inc.",
"name": "@transcend-io/cli",
"description": "Small package containing useful typescript utilities.",
"version": "6.7.0",
"version": "6.8.0",
"homepage": "https://github.com/transcend-io/cli",
"repository": {
"type": "git",
Expand All @@ -27,6 +27,7 @@
"tr-pull": "./build/cli-pull.js",
"tr-pull-consent-metrics": "./build/cli-pull-consent-metrics.js",
"tr-pull-consent-preferences": "./build/cli-pull-consent-preferences.js",
"tr-pull-datapoints": "./build/cli-pull-datapoints.js",
"tr-push": "./build/cli-push.js",
"tr-request-approve": "./build/cli-request-approve.js",
"tr-request-cancel": "./build/cli-request-cancel.js",
Expand Down Expand Up @@ -65,7 +66,7 @@
"@transcend-io/handlebars-utils": "^1.1.0",
"@transcend-io/internationalization": "^1.6.0",
"@transcend-io/persisted-state": "^1.0.4",
"@transcend-io/privacy-types": "^4.91.0",
"@transcend-io/privacy-types": "^4.92.0",
"@transcend-io/secret-value": "^1.2.0",
"@transcend-io/type-utils": "^1.5.0",
"bluebird": "^3.7.2",
Expand Down
129 changes: 129 additions & 0 deletions src/cli-pull-datapoints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#!/usr/bin/env node
import uniq from 'lodash/uniq';
import groupBy from 'lodash/groupBy';

import yargs from 'yargs-parser';
import { logger } from './logger';
import colors from 'colors';
import { buildTranscendGraphQLClient } from './graphql';
import { ADMIN_DASH_DATAPOINTS, DEFAULT_TRANSCEND_API } from './constants';
import { pullAllDatapoints } from './data-inventory';
import { writeCsv } from './cron';
import { splitCsvToList } from './requests';
import { DataCategoryType } from '@transcend-io/privacy-types';

/**
* Sync datapoints from Transcend inventory to a CSV
*
* Dev Usage:
* yarn ts-node ./src/cli-pull-datapoints.ts --auth=$TRANSCEND_API_KEY
*
* Standard usage
* yarn cli-pull-datapoints --auth=$TRANSCEND_API_KEY
*/
async function main(): Promise<void> {
// Parse command line arguments
const {
file = './datapoints.csv',
transcendUrl = DEFAULT_TRANSCEND_API,
auth,
dataSiloIds = '',
includeAttributes = 'false',
includeGuessedCategories = 'false',
parentCategories = '',
subCategories = '',
} = yargs(process.argv.slice(2));

// Ensure auth is passed
if (!auth) {
logger.error(
colors.red(
'A Transcend API key must be provided. You can specify using --auth=$TRANSCEND_API_KEY',
),
);
process.exit(1);
}

// Validate trackerStatuses
const parsedParentCategories = splitCsvToList(
parentCategories,
) as DataCategoryType[];
const invalidParentCategories = parsedParentCategories.filter(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(type) => !Object.values(DataCategoryType).includes(type as any),
);
if (invalidParentCategories.length > 0) {
logger.error(
colors.red(
`Failed to parse parentCategories:"${invalidParentCategories.join(
',',
)}".\n` +
`Expected one of: \n${Object.values(DataCategoryType).join('\n')}`,
),
);
process.exit(1);
}

try {
// Create a GraphQL client
const client = buildTranscendGraphQLClient(transcendUrl, auth);

const dataPoints = await pullAllDatapoints(client, {
dataSiloIds: splitCsvToList(dataSiloIds),
includeGuessedCategories: includeGuessedCategories === 'true',
parentCategories: parsedParentCategories,
includeAttributes: includeAttributes === 'true',
subCategories: splitCsvToList(subCategories), // TODO: https://transcend.height.app/T-40482 - do by name not ID
});

logger.info(colors.magenta(`Writing datapoints to file "${file}"...`));
let headers: string[] = [];
const inputs = dataPoints.map((point) => {
const result = {
'Property ID': point.id,
'Data Silo': point.dataSilo.title,
Object: point.dataPoint.name,
'Object Path': point.dataPoint.path.join('.'),
Property: point.name,
'Property Description': point.description,
'Data Categories': point.categories
.map((category) => `${category.category}:${category.name}`)
.join(', '),
'Guessed Category': point.pendingCategoryGuesses?.[0]
? `${point.pendingCategoryGuesses![0]!.category.category}:${
point.pendingCategoryGuesses![0]!.category.name
}`
: '',
'Processing Purposes': point.purposes
.map((purpose) => `${purpose.purpose}:${purpose.name}`)
.join(', '),
...Object.entries(
groupBy(
point.attributeValues || [],
({ attributeKey }) => attributeKey.name,
),
).reduce((acc, [key, values]) => {
acc[key] = values.map((value) => value.name).join(',');
return acc;
}, {} as Record<string, string>),
};
headers = uniq([...headers, ...Object.keys(result)]);
return result;
});
writeCsv(file, inputs, headers);
} catch (err) {
logger.error(
colors.red(`An error occurred syncing the datapoints: ${err.message}`),
);
process.exit(1);
}

// Indicate success
logger.info(
colors.green(
`Successfully synced datapoints to disk at ${file}! View at ${ADMIN_DASH_DATAPOINTS}`,
),
);
}

main();
4 changes: 2 additions & 2 deletions src/cli-request-export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ async function main(): Promise<void> {
logger.error(
colors.red(
`Failed to parse actions:"${invalidActions.join(',')}".\n` +
`Expected one of: \n${Object.values(RequestAction).join('\n')}`,
`Expected one of: \n${Object.values(RequestAction).join('\n')}`,
),
);
process.exit(1);
Expand All @@ -87,7 +87,7 @@ async function main(): Promise<void> {
logger.error(
colors.red(
`Failed to parse statuses:"${invalidStatuses.join(',')}".\n` +
`Expected one of: \n${Object.values(RequestStatus).join('\n')}`,
`Expected one of: \n${Object.values(RequestStatus).join('\n')}`,
),
);
process.exit(1);
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TranscendInput } from './codecs';
export const ADMIN_DASH = 'https://app.transcend.io';

export const ADMIN_DASH_INTEGRATIONS = `${ADMIN_DASH}/infrastructure/integrations`;
export const ADMIN_DASH_DATAPOINTS = `${ADMIN_DASH}/data-map/data-inventory/data-points`;

/**
* Override default transcend API url using
Expand Down
1 change: 1 addition & 0 deletions src/data-inventory/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './pullAllDatapoints';
Loading

0 comments on commit 4eafcf0

Please sign in to comment.