@transcend-io/cli 7.0.0-alpha.7 → 7.0.0-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -44
- package/dist/bin/bash-complete.js +1 -1
- package/dist/bin/cli.js +1 -1
- package/dist/bin/deprecated-command.js +1 -1
- package/dist/{chunk-5TDUSKDZ.js → chunk-355AXZQZ.js} +1 -1
- package/dist/{chunk-AYMLP7SL.js → chunk-4QPDLGCV.js} +1 -1
- package/dist/{chunk-PNOEWENG.js → chunk-B6ZR2J5H.js} +1 -1
- package/dist/{chunk-F5KKB33H.js → chunk-BQKOX64R.js} +1 -1
- package/dist/{chunk-NYDK4VPA.js → chunk-DKNP2CU7.js} +1 -1
- package/dist/{chunk-DLIWRRVR.js → chunk-FSIXUJFP.js} +21 -17
- package/dist/{chunk-QXOUJ7DT.js → chunk-HZNRGCLH.js} +1 -1
- package/dist/{chunk-MLF3XCRS.js → chunk-J2ZBQKW5.js} +1 -1
- package/dist/{chunk-LE6MXFBT.js → chunk-PDDJKJLS.js} +1 -1
- package/dist/chunk-RLLIDCPR.js +8 -0
- package/dist/{chunk-T4AGEIE3.js → chunk-S7ZUY224.js} +1 -1
- package/dist/{chunk-QAPBYN24.js → chunk-ZES4XGUM.js} +1 -1
- package/dist/{chunk-4HZHZ32O.js → chunk-ZEXWBTLE.js} +1 -1
- package/dist/impl-27HXB774.js +8 -0
- package/dist/{impl-46IFTUCW.js → impl-2IJTNY4B.js} +1 -1
- package/dist/{impl-7W6EBZXZ.js → impl-45AP5ZX5.js} +1 -1
- package/dist/impl-4L5FLYLP.js +1 -0
- package/dist/{impl-QR3ARAMQ.js → impl-5WT54GJ6.js} +1 -1
- package/dist/{impl-YJ2FK37I.js → impl-6TJVPXFA.js} +1 -1
- package/dist/{impl-QYJFDBIV.js → impl-7MZ2GRX2.js} +1 -1
- package/dist/{impl-K2ZB3AKB.js → impl-7X6DB6TS.js} +1 -1
- package/dist/{impl-PS2DUGWP.js → impl-AOO42JWA.js} +1 -1
- package/dist/{impl-QTDGR3SU.js → impl-CINASI7X.js} +1 -1
- package/dist/{impl-6J4LHKU5.js → impl-CJQKXJK5.js} +1 -1
- package/dist/{impl-YT7F6KTN.js → impl-CMZBIUTF.js} +1 -1
- package/dist/{impl-22YTZZ5H.js → impl-CUATNMND.js} +1 -1
- package/dist/{impl-52S3Z4ZE.js → impl-FFM7HH6E.js} +1 -1
- package/dist/{impl-UYCGE2TQ.js → impl-GURHBO3R.js} +1 -1
- package/dist/{impl-TLUPGHWG.js → impl-HHBFHJSK.js} +1 -1
- package/dist/{impl-IDWP2NIG.js → impl-KTX24C4K.js} +1 -1
- package/dist/{impl-LNLKIPIP.js → impl-KZXH3Y3W.js} +1 -1
- package/dist/impl-LM4DMVYI.js +1 -0
- package/dist/{impl-75FHAT4R.js → impl-LQ275RBM.js} +1 -1
- package/dist/{impl-GSXYV2XR.js → impl-M7DBU4GI.js} +1 -1
- package/dist/{impl-YBSUR2MT.js → impl-M7QB2XPW.js} +1 -1
- package/dist/{impl-KQ2R65SG.js → impl-MDZJCI4H.js} +1 -1
- package/dist/{impl-MFDS7DPF.js → impl-N5VJXHO7.js} +1 -1
- package/dist/{impl-Q65ZCWEQ.js → impl-NN2CT2AA.js} +1 -1
- package/dist/{impl-URMADXQA.js → impl-PRQTJKHF.js} +1 -1
- package/dist/{impl-4WQTM3GN.js → impl-RALRZG3L.js} +1 -1
- package/dist/impl-SBRSPHTB.js +1 -0
- package/dist/impl-SCSRN2JZ.js +1 -0
- package/dist/{impl-ZBWVSFDE.js → impl-SZVOCN3A.js} +1 -1
- package/dist/{impl-UV5ERXN5.js → impl-TE32S5WA.js} +1 -1
- package/dist/{impl-JRA6GN3V.js → impl-TONFW3HX.js} +1 -1
- package/dist/{impl-ISWFGOUS.js → impl-TX7YFUXO.js} +1 -1
- package/dist/{impl-W454HAAT.js → impl-U3BDV3RA.js} +1 -1
- package/dist/{impl-NVBTQCSL.js → impl-V3A77FGE.js} +1 -1
- package/dist/{impl-ZEEUCWKF.js → impl-V3YOC4MQ.js} +1 -1
- package/dist/{impl-7C43442T.js → impl-WOYVKA3U.js} +1 -1
- package/dist/{impl-CLLZCY76.js → impl-Y4NEIKHE.js} +1 -1
- package/dist/index.js +1 -1
- package/package.json +3 -2
- package/dist/chunk-IQZKONXI.js +0 -8
- package/dist/impl-ICGIPWVJ.js +0 -1
- package/dist/impl-ULVQLOA5.js +0 -1
- package/dist/impl-VT26YO3N.js +0 -1
- package/dist/impl-ZXDLJ2TY.js +0 -8
package/README.md
CHANGED
|
@@ -32,8 +32,6 @@
|
|
|
32
32
|
- [`transcend consent upload-cookies-from-csv`](#transcend-consent-upload-cookies-from-csv)
|
|
33
33
|
- [`transcend consent upload-data-flows-from-csv`](#transcend-consent-upload-data-flows-from-csv)
|
|
34
34
|
- [`transcend consent upload-preferences`](#transcend-consent-upload-preferences)
|
|
35
|
-
- [`transcend consent consent-manager-service-json-to-yml`](#transcend-consent-consent-manager-service-json-to-yml)
|
|
36
|
-
- [`transcend consent consent-managers-to-business-entities`](#transcend-consent-consent-managers-to-business-entities)
|
|
37
35
|
- [`transcend inventory pull`](#transcend-inventory-pull)
|
|
38
36
|
- [Scopes](#scopes)
|
|
39
37
|
- [Usage](#usage-1)
|
|
@@ -49,6 +47,8 @@
|
|
|
49
47
|
- [`transcend inventory pull-unstructured-discovery-files`](#transcend-inventory-pull-unstructured-discovery-files)
|
|
50
48
|
- [`transcend inventory derive-data-silos-from-data-flows`](#transcend-inventory-derive-data-silos-from-data-flows)
|
|
51
49
|
- [`transcend inventory derive-data-silos-from-data-flows-cross-instance`](#transcend-inventory-derive-data-silos-from-data-flows-cross-instance)
|
|
50
|
+
- [`transcend inventory consent-manager-service-json-to-yml`](#transcend-inventory-consent-manager-service-json-to-yml)
|
|
51
|
+
- [`transcend inventory consent-managers-to-business-entities`](#transcend-inventory-consent-managers-to-business-entities)
|
|
52
52
|
- [`transcend admin generate-api-keys`](#transcend-admin-generate-api-keys)
|
|
53
53
|
- [Usage](#usage-4)
|
|
54
54
|
- [`transcend migration sync-ot`](#transcend-migration-sync-ot)
|
|
@@ -86,7 +86,7 @@ _The CLI commands which interact with Transcend's API will default to using Tran
|
|
|
86
86
|
|
|
87
87
|
## transcend.yml
|
|
88
88
|
|
|
89
|
-
Within your git repositories, you can define a file `transcend.yml`. This file allows you define part of your Data Map in code. Using the
|
|
89
|
+
Within your git repositories, you can define a file `transcend.yml`. This file allows you define part of your Data Map in code. Using the CLI, you can sync that configuration back to the Transcend Admin Dashboard (https://app.transcend.io/privacy-requests/connected-services).
|
|
90
90
|
|
|
91
91
|
You can find various examples for your `transcend.yml` file in the [examples/](./examples/) folder. If you are looking for a starting point to copy and paste, [simple.yml](./examples/simple.yml) is a good place to start. This file is annotated with links and documentations that new members of your team can use if they come across the file.
|
|
92
92
|
|
|
@@ -107,7 +107,7 @@ The structure of `transcend.yml` looks something like the following:
|
|
|
107
107
|
# See https://docs.transcend.io/docs/authentication
|
|
108
108
|
# Define API keys that may be shared across data silos
|
|
109
109
|
# in the data map. When creating new data silos through the YAML
|
|
110
|
-
#
|
|
110
|
+
# CLI, it is possible to specify which API key should be associated
|
|
111
111
|
# with the newly created data silo.
|
|
112
112
|
api-keys:
|
|
113
113
|
- title: Webhook Key
|
|
@@ -572,7 +572,7 @@ FLAGS
|
|
|
572
572
|
[--sombraAuth] The Sombra internal key, use for additional authentication when self-hosting Sombra
|
|
573
573
|
[--pageLimit] The page limit to use when pulling in pages of identifiers [default = 100]
|
|
574
574
|
[--skipRequestCount] Whether to skip the count of all outstanding requests. This is required to render the progress bar, but can take a long time to run if you have a large number of outstanding requests to process. In that case, we recommend setting skipRequestCount=true so that you can still proceed with fetching the identifiers [default = false]
|
|
575
|
-
[--chunkSize] Maximum number of rows per CSV file. For large datasets, the output will be automatically split into multiple files to avoid file system size limits. Each file will contain at most this many rows [default =
|
|
575
|
+
[--chunkSize] Maximum number of rows per CSV file. For large datasets, the output will be automatically split into multiple files to avoid file system size limits. Each file will contain at most this many rows [default = 10000]
|
|
576
576
|
-h --help Print help information and exit
|
|
577
577
|
```
|
|
578
578
|
|
|
@@ -583,7 +583,7 @@ USAGE
|
|
|
583
583
|
transcend request cron mark-identifiers-completed (--auth value) (--dataSiloId value) [--file value] [--transcendUrl value] [--sombraAuth value]
|
|
584
584
|
transcend request cron mark-identifiers-completed --help
|
|
585
585
|
|
|
586
|
-
This command takes the output of
|
|
586
|
+
This command takes the output of "transcend request cron pull-identifiers" and notifies Transcend that all of the requests in the CSV have been processed.
|
|
587
587
|
This is used in the workflow like:
|
|
588
588
|
|
|
589
589
|
1. Pull identifiers to CSV:
|
|
@@ -834,42 +834,6 @@ Specifying the backend URL, needed for US hosted backend infrastructure:
|
|
|
834
834
|
transcend consent upload-preferences --auth=$TRANSCEND_API_KEY --partition=4d1c5daa-90b7-4d18-aa40-f86a43d2c726 --consentUrl=https://consent.us.transcend.io
|
|
835
835
|
```
|
|
836
836
|
|
|
837
|
-
### `transcend consent consent-manager-service-json-to-yml`
|
|
838
|
-
|
|
839
|
-
```txt
|
|
840
|
-
USAGE
|
|
841
|
-
transcend consent consent-manager-service-json-to-yml [--file value] [--output value]
|
|
842
|
-
transcend consent consent-manager-service-json-to-yml --help
|
|
843
|
-
|
|
844
|
-
Import the services from an airgap.js file into a Transcend instance.
|
|
845
|
-
|
|
846
|
-
Step 1) Run `await airgap.getMetadata()` on a site with airgap
|
|
847
|
-
Step 2) Right click on the printed object, and click `Copy object`
|
|
848
|
-
Step 3) Place output of file in a file named `services.json`
|
|
849
|
-
Step 4) Run `transcend consent consent-manager-service-json-to-yml --file=./services.json --output=./transcend.yml`
|
|
850
|
-
Step 5) Run `transcend inventory push --auth=$TRANSCEND_API_KEY --file=./transcend.yml --classifyService=true`
|
|
851
|
-
|
|
852
|
-
FLAGS
|
|
853
|
-
[--file] Path to the services.json file, output of await airgap.getMetadata() [default = ./services.json]
|
|
854
|
-
[--output] Path to the output transcend.yml to write to [default = ./transcend.yml]
|
|
855
|
-
-h --help Print help information and exit
|
|
856
|
-
```
|
|
857
|
-
|
|
858
|
-
### `transcend consent consent-managers-to-business-entities`
|
|
859
|
-
|
|
860
|
-
```txt
|
|
861
|
-
USAGE
|
|
862
|
-
transcend consent consent-managers-to-business-entities (--consentManagerYmlFolder value) [--output value]
|
|
863
|
-
transcend consent consent-managers-to-business-entities --help
|
|
864
|
-
|
|
865
|
-
This command allows for converting a folder or Consent Manager transcend.yml files into a single transcend.yml file where each consent manager configuration is a Business Entity in the data inventory.
|
|
866
|
-
|
|
867
|
-
FLAGS
|
|
868
|
-
--consentManagerYmlFolder Path to the folder of Consent Manager transcend.yml files to combine
|
|
869
|
-
[--output] Path to the output transcend.yml with business entity configuration [default = ./combined-business-entities.yml]
|
|
870
|
-
-h --help Print help information and exit
|
|
871
|
-
```
|
|
872
|
-
|
|
873
837
|
### `transcend inventory pull`
|
|
874
838
|
|
|
875
839
|
```txt
|
|
@@ -1383,6 +1347,42 @@ FLAGS
|
|
|
1383
1347
|
-h --help Print help information and exit
|
|
1384
1348
|
```
|
|
1385
1349
|
|
|
1350
|
+
### `transcend inventory consent-manager-service-json-to-yml`
|
|
1351
|
+
|
|
1352
|
+
```txt
|
|
1353
|
+
USAGE
|
|
1354
|
+
transcend inventory consent-manager-service-json-to-yml [--file value] [--output value]
|
|
1355
|
+
transcend inventory consent-manager-service-json-to-yml --help
|
|
1356
|
+
|
|
1357
|
+
Import the services from an airgap.js file into a Transcend instance.
|
|
1358
|
+
|
|
1359
|
+
Step 1) Run `await airgap.getMetadata()` on a site with airgap
|
|
1360
|
+
Step 2) Right click on the printed object, and click `Copy object`
|
|
1361
|
+
Step 3) Place output of file in a file named `services.json`
|
|
1362
|
+
Step 4) Run `transcend consent consent-manager-service-json-to-yml --file=./services.json --output=./transcend.yml`
|
|
1363
|
+
Step 5) Run `transcend inventory push --auth=$TRANSCEND_API_KEY --file=./transcend.yml --classifyService=true`
|
|
1364
|
+
|
|
1365
|
+
FLAGS
|
|
1366
|
+
[--file] Path to the services.json file, output of await airgap.getMetadata() [default = ./services.json]
|
|
1367
|
+
[--output] Path to the output transcend.yml to write to [default = ./transcend.yml]
|
|
1368
|
+
-h --help Print help information and exit
|
|
1369
|
+
```
|
|
1370
|
+
|
|
1371
|
+
### `transcend inventory consent-managers-to-business-entities`
|
|
1372
|
+
|
|
1373
|
+
```txt
|
|
1374
|
+
USAGE
|
|
1375
|
+
transcend inventory consent-managers-to-business-entities (--consentManagerYmlFolder value) [--output value]
|
|
1376
|
+
transcend inventory consent-managers-to-business-entities --help
|
|
1377
|
+
|
|
1378
|
+
This command allows for converting a folder or Consent Manager transcend.yml files into a single transcend.yml file where each consent manager configuration is a Business Entity in the data inventory.
|
|
1379
|
+
|
|
1380
|
+
FLAGS
|
|
1381
|
+
--consentManagerYmlFolder Path to the folder of Consent Manager transcend.yml files to combine
|
|
1382
|
+
[--output] Path to the output transcend.yml with business entity configuration [default = ./combined-business-entities.yml]
|
|
1383
|
+
-h --help Print help information and exit
|
|
1384
|
+
```
|
|
1385
|
+
|
|
1386
1386
|
### `transcend admin generate-api-keys`
|
|
1387
1387
|
|
|
1388
1388
|
```txt
|
|
@@ -1392,7 +1392,7 @@ USAGE
|
|
|
1392
1392
|
|
|
1393
1393
|
This command allows for creating API keys across multiple Transcend instances. This is useful for customers that are managing many Transcend instances and need to regularly create, cycle or delete API keys across all of their instances.
|
|
1394
1394
|
|
|
1395
|
-
Unlike the other commands that rely on API key authentication, this command relies upon username/password authentication. This command will spit out the API keys into a JSON file, and that JSON file can be used in subsequent
|
|
1395
|
+
Unlike the other commands that rely on API key authentication, this command relies upon username/password authentication. This command will spit out the API keys into a JSON file, and that JSON file can be used in subsequent CLI commands.
|
|
1396
1396
|
|
|
1397
1397
|
Authentication requires your email and password for the Transcend account. This command will only generate API keys for Transcend instances where you have the permission to "Manage API Keys".
|
|
1398
1398
|
|
|
@@ -1636,4 +1636,4 @@ export async function main(): Promise<void> {
|
|
|
1636
1636
|
|
|
1637
1637
|
## Proxy usage
|
|
1638
1638
|
|
|
1639
|
-
If you are trying to use the
|
|
1639
|
+
If you are trying to use the CLI inside a corporate firewall and need to send traffic through a proxy, you can do so via the `http_proxy` environment variable,with a command like `http_proxy=http://localhost:5051 transcend inventory pull --auth=$TRANSCEND_API_KEY`.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as s}from"../chunk-XMGVDVM2.js";import{a as o}from"../chunk-
|
|
2
|
+
import{a as s}from"../chunk-XMGVDVM2.js";import{a as o}from"../chunk-FSIXUJFP.js";import"../chunk-RLLIDCPR.js";import"../chunk-APA5PR4U.js";import"../chunk-J2ZBQKW5.js";import"../chunk-EZCJGIOS.js";import{proposeCompletions as r}from"@stricli/core";var t=process.argv.slice(3);process.env.COMP_LINE?.endsWith(" ")&&t.push("");await r(o,t,s(process));try{for(let{completion:p}of await r(o,t,s(process)))process.stdout.write(`${p}
|
|
3
3
|
`)}catch{}
|
package/dist/bin/cli.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as o}from"../chunk-XMGVDVM2.js";import{a as r}from"../chunk-
|
|
2
|
+
import{a as o}from"../chunk-XMGVDVM2.js";import{a as r}from"../chunk-FSIXUJFP.js";import"../chunk-RLLIDCPR.js";import"../chunk-APA5PR4U.js";import"../chunk-J2ZBQKW5.js";import"../chunk-EZCJGIOS.js";import{run as i}from"@stricli/core";await i(r,process.argv.slice(2),o(process));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as n}from"../chunk-
|
|
2
|
+
import{a as n}from"../chunk-FSIXUJFP.js";import"../chunk-RLLIDCPR.js";import{a as r}from"../chunk-OERYFLN2.js";import"../chunk-APA5PR4U.js";import"../chunk-J2ZBQKW5.js";import"../chunk-EZCJGIOS.js";import{generateHelpTextForAllCommands as c}from"@stricli/core";var s={"tr-build-xdi-sync-endpoint":["consent","build-xdi-sync-endpoint"],"tr-consent-manager-service-json-to-yml":["inventory","consent-manager-service-json-to-yml"],"tr-consent-managers-to-business-entities":["inventory","consent-managers-to-business-entities"],"tr-cron-mark-identifiers-completed":["request","cron","mark-identifiers-completed"],"tr-cron-pull-identifiers":["request","cron","pull-identifiers"],"tr-derive-data-silos-from-data-flows":["inventory","derive-data-silos-from-data-flows"],"tr-derive-data-silos-from-data-flows-cross-instance":["inventory","derive-data-silos-from-data-flows-cross-instance"],"tr-discover-silos":["inventory","discover-silos"],"tr-generate-api-keys":["admin","generate-api-keys"],"tr-manual-enrichment-pull-identifiers":["request","preflight","pull-identifiers"],"tr-manual-enrichment-push-identifiers":["request","preflight","push-identifiers"],"tr-mark-request-data-silos-completed":["request","system","mark-request-data-silos-completed"],"tr-pull":["inventory","pull"],"tr-pull-consent-metrics":["consent","pull-consent-metrics"],"tr-pull-consent-preferences":["consent","pull-consent-preferences"],"tr-pull-datapoints":["inventory","pull-datapoints"],"tr-pull-pull-unstructured-discovery-files":["inventory","pull-unstructured-discovery-files"],"tr-push":["inventory","push"],"tr-request-approve":["request","approve"],"tr-request-cancel":["request","cancel"],"tr-request-download-files":["request","download-files"],"tr-request-enricher-restart":["request","enricher-restart"],"tr-request-export":["request","export"],"tr-request-mark-silent":["request","mark-silent"],"tr-request-notify-additional-time":["request","notify-additional-time"],"tr-request-reject-unverified-identifiers":["request","reject-unverified-identifiers"],"tr-request-restart":["request","restart"],"tr-request-upload":["request","upload"],"tr-retry-request-data-silos":["request","system","retry-request-data-silos"],"tr-scan-packages":["inventory","scan-packages"],"tr-skip-preflight-jobs":["request","skip-preflight-jobs"],"tr-skip-request-data-silos":["request","system","skip-request-data-silos"],"tr-sync-ot":["migration","sync-ot"],"tr-update-consent-manager":["consent","update-consent-manager"],"tr-upload-consent-preferences":["consent","upload-consent-preferences"],"tr-upload-cookies-from-csv":["consent","upload-cookies-from-csv"],"tr-upload-data-flows-from-csv":["consent","upload-data-flows-from-csv"],"tr-upload-preferences":["consent","upload-preferences"]};function m(t){return c(n).find(o=>o[0]===`${n.config.name} ${t.join(" ")}`)?.[1]}function i(t){r.log("[DEPRECATION NOTICE]");let e=s[t];if(!e){let a=Object.entries(s).map(([d,l])=>`\`${d}\` -> \`${n.config.name} ${l.join(" ")}\``).join(`
|
|
3
3
|
`);r.log(`This command is deprecated as of v7.0.0. Here is a list of new commands, mapped to their legacy command names:
|
|
4
4
|
${a}`);return}r.log(`\`${t}\` is deprecated as of v7.0.0.
|
|
5
5
|
Use \`${n.config.name} ${e.join(" ")}\` instead.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{q as F}from"./chunk-
|
|
1
|
+
import{q as F}from"./chunk-HZNRGCLH.js";import{De as O,_b as G,a as _,b as S,pe as A,qe as P,ve as N,wa as k}from"./chunk-PDDJKJLS.js";import{a as r}from"./chunk-OERYFLN2.js";import{e as I}from"./chunk-APA5PR4U.js";import*as e from"io-ts";import{decodeCodec as V}from"@transcend-io/type-utils";var X=e.type({identifier:e.string,type:e.string,coreIdentifier:e.string,dataSiloId:e.string,requestId:e.string,nonce:e.string,requestCreatedAt:e.string,daysUntilOverdue:e.number,attributes:e.array(e.type({key:e.string,values:e.array(e.string)}))});async function U(t,{dataSiloId:n,limit:m=100,offset:o=0,requestType:s}){try{let i=await t.get(`v1/data-silo/${n}/pending-requests/${s}`,{searchParams:{offset:o,limit:m}}).json(),{items:c}=V(e.type({items:e.array(X)}),i);return c}catch(i){throw new Error(`Received an error from server: ${i?.response?.body||i?.message}`)}}import*as T from"io-ts";var L=T.type({nonce:T.string,identifier:T.string});async function B(t,{nonce:n,identifier:m}){try{return await t.put("v1/data-silo",{headers:{"x-transcend-nonce":n},json:{profiles:[{profileId:m}]}}),!0}catch(o){if(o.response?.statusCode===409)return!1;throw new Error(`Received an error from server: ${o?.response?.body||o?.message}`)}}import w from"colors";import j from"cli-progress";async function de({file:t,dataSiloId:n,auth:m,sombraAuth:o,concurrency:s=100,transcendUrl:i=I}){let c=await P(i,m,o);r.info(w.magenta(`Reading "${t}" from disk`));let d=F(t,L);r.info(w.magenta(`Notifying Transcend for data silo "${n}" marking "${d.length}" identifiers as completed.`));let a=new Date().getTime(),p=new j.SingleBar({},j.Presets.shades_classic),h=0,f=0,g=0;p.start(d.length,0),await S(d,async C=>{try{await B(c,C)?h+=1:f+=1}catch(u){r.error(w.red(`Error notifying Transcend for identifier "${C.identifier}" - ${u.message}`)),g+=1}p.update(h+f)},{concurrency:s}),p.stop();let l=new Date().getTime()-a;if(r.info(w.green(`Successfully notified Transcend for ${h} identifiers in "${l/1e3}" seconds!`)),f&&r.info(w.magenta(`There were ${f} identifiers that were not in a state to be updated.They likely have already been resolved.`)),g)throw r.error(w.red(`There were ${g} identifiers that failed to be updated. Please review the logs for more information.`)),new Error("Failed to update all identifiers");return d.length}import W from"colors";import Q from"cli-progress";import{RequestDataSiloStatus as Y}from"@transcend-io/privacy-types";async function we({requestIds:t,dataSiloId:n,auth:m,concurrency:o=100,status:s=Y.Resolved,transcendUrl:i=I}){let c=A(i,m),d=new Date().getTime(),a=new Q.SingleBar({},Q.Presets.shades_classic);r.info(W.magenta(`Notifying Transcend for data silo "${n}" marking "${t.length}" requests as completed.`));let p=0;a.start(t.length,0),await S(t,async g=>{let y=await O(c,{requestId:g,dataSiloId:n});try{await G(c,k,{requestDataSiloId:y.id,status:s})}catch(l){if(!l.message.includes("Client error: Request must be active:"))throw l}p+=1,a.update(p)},{concurrency:o}),a.stop();let f=new Date().getTime()-d;return r.info(W.green(`Successfully notified Transcend in "${f/1e3}" seconds!`)),t.length}import v from"colors";import z from"cli-progress";async function Re({dataSiloId:t,auth:n,sombraAuth:m,actions:o,apiPageSize:s=100,savePageSize:i=1e3,onSave:c,transcendUrl:d=I,skipRequestCount:a=!1}){if(i%s!==0)throw new Error(`savePageSize must be a multiple of apiPageSize. savePageSize: ${i}, apiPageSize: ${s}`);let p=await P(d,n,m),h=A(d,n),f=0;a||(f=await N(h,{dataSiloId:t})),r.info(v.magenta(`Pulling ${a?"all":f} outstanding request identifiers for data silo: "${t}" for requests of types "${o.join('", "')}"`));let g=new Date().getTime(),y=new z.SingleBar({},z.Presets.shades_classic),l=new Set,C=[],u=[];a||y.start(f,0),await _(o,async q=>{let D=0,R=!0;for(;R;){let $=await U(p,{dataSiloId:t,limit:s,offset:D,requestType:q}),x=$.map(b=>(l.add(b.requestId),{...b,action:q})),J=x.map(({attributes:b,...K})=>({...K,...b.reduce((M,E)=>Object.assign(M,{[E.key]:E.values.join(",")}),{})}));C.push(...x),u.push(...J),u.length>=i&&(await c(u),u=[]),R=$.length===s,D+=s,a?r.info(v.magenta(`Pulled ${$.length} outstanding identifiers for ${l.size} requests`)):y.update(l.size)}}),u.length>0&&await c(u),a||y.stop();let H=new Date().getTime()-g;return r.info(v.green(`Successfully pulled ${C.length} outstanding identifiers from ${l.size} requests in "${H/1e3}" seconds!`)),{identifiers:C}}export{X as a,U as b,L as c,B as d,de as e,we as f,Re as g};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{c as u}from"./chunk-
|
|
1
|
+
import{c as u}from"./chunk-ZES4XGUM.js";import{a as E}from"./chunk-OERYFLN2.js";import{readFileSync as b}from"fs";import{findAllWithRegex as F}from"@transcend-io/type-utils";import{CodePackageType as w}from"@transcend-io/privacy-types";var N=/target ('|")(.*?)('|")/,O=/pod ('|")(.*?)('|")(, ('|")~> (.+?)('|")|)/,y={supportedFiles:["Podfile"],ignoreDirs:["Pods"],scanFunction:e=>{let n=b(e,"utf-8"),o=F({value:new RegExp(N,"g"),matches:["quote1","name","quote2"]},n),c=F({value:new RegExp(O,"g"),matches:["quote1","name","quote2","extra","quote3","version","quote4"]},n);return o.map((t,p)=>({name:t.name,type:w.CocoaPods,softwareDevelopmentKits:c.filter(r=>r.matchIndex>t.matchIndex&&(!o[p+1]||r.matchIndex<o[p+1].matchIndex)).map(r=>({name:r.name,version:r.version}))}))}};import{readFileSync as T}from"fs";import{findAllWithRegex as l}from"@transcend-io/type-utils";import{dirname as h}from"path";var K=/implementation( *)('|")(.+?):(.+?):(.+?|)('|")/,M=/apply plugin: *('|")(.+?)(:(.+?)|)('|")/,j=/implementation group:( *)('|")(.+?)('|"),( *)name:( *)('|")(.+?)('|"),( *)version:( *)('|")(.+?)('|")/,L=/applicationId( *)"(.+?)"/,S={supportedFiles:["build.gradle**"],ignoreDirs:["gradle-app.setting","gradle-wrapper.jar","gradle-wrapper.properties"],scanFunction:e=>{let n=T(e,"utf-8"),o=h(e),c=l({value:new RegExp(K,"g"),matches:["space","quote1","name","path","version","quote2"]},n),a=l({value:new RegExp(M,"g"),matches:["quote1","name","group","version","quote2"]},n),t=l({value:new RegExp(j,"g"),matches:["space1","quote1","group","quote2","space2","space3","quote3","name","quote4","space4","space5","quote5","version","quote6"]},n),p=l({value:new RegExp(L,"g"),matches:["space","name"]},n);if(p.length>1)throw new Error(`Expected only one applicationId per file: ${e}`);return[{name:p[0]?.name||o.split("/").pop(),softwareDevelopmentKits:[...c,...t,...a].map(r=>({name:r.name,version:r.version||void 0}))}]}};import{readFileSync as $}from"fs";import{dirname as J}from"path";var x={supportedFiles:["package.json"],ignoreDirs:["node_modules","serverless-build","lambda-build"],scanFunction:e=>{let n=$(e,"utf-8"),o=J(e),c=JSON.parse(n),{name:a,description:t,dependencies:p={},devDependencies:r={},optionalDependencies:i={}}=c;return[{name:a||o.split("/").pop(),description:t,softwareDevelopmentKits:[...Object.entries(p).map(([s,m])=>({name:s,version:typeof m=="string"?m:void 0})),...Object.entries(r).map(([s,m])=>({name:s,version:typeof m=="string"?m:void 0,isDevDependency:!0})),...Object.entries(i).map(([s,m])=>({name:s,version:typeof m=="string"?m:void 0}))]}]}};import{readFileSync as R}from"fs";import{findAllWithRegex as X}from"@transcend-io/type-utils";import{dirname as U,join as W}from"path";import{CodePackageType as Y}from"@transcend-io/privacy-types";var V=/(.+?)(=+)(.+)/,H=/name *= *('|")(.+?)('|")/,Q=/description *= *('|")(.+?)('|")/,P={supportedFiles:["requirements.txt"],ignoreDirs:["build","lib","lib64"],scanFunction:e=>{let n=R(e,"utf-8"),o=U(e),a=u(o).find(s=>s==="setup.py"),t=a?R(W(o,a),"utf-8"):void 0,p=t?(H.exec(t)||[])[2]:void 0,r=t?(Q.exec(t)||[])[2]:void 0,i=X({value:new RegExp(V,"g"),matches:["name","equals","version"]},n);return[{name:p||o.split("/").pop(),description:r||void 0,type:Y.RequirementsTxt,softwareDevelopmentKits:i.map(s=>({name:s.name,version:s.version}))}]}};import{readFileSync as G}from"fs";import{findAllWithRegex as z}from"@transcend-io/type-utils";import{dirname as B}from"path";import{CodePackageType as Z}from"@transcend-io/privacy-types";var ee=/gem *('|")(.+?)('|")(, *('|")(.+?)('|")|)/,ne=/spec\.name *= *('|")(.+?)('|")/,oe=/spec\.description *= *('|")(.+?)('|")/,te=/spec\.summary *= *('|")(.+?)('|")/,k={supportedFiles:["Gemfile"],ignoreDirs:["bin"],scanFunction:e=>{let n=G(e,"utf-8"),o=B(e),a=u(o).find(s=>s===".gemspec"),t=a?G(a,"utf-8"):void 0,p=t?(ne.exec(t)||[])[2]:void 0,r=t?(oe.exec(t)||te.exec(t)||[])[1]:void 0,i=z({value:new RegExp(ee,"g"),matches:["quote1","name","quote2","hasVersion","quote3","version","quote4"]},n);return[{name:p||o.split("/").pop(),description:r||void 0,type:Z.RequirementsTxt,softwareDevelopmentKits:i.map(s=>({name:s.name,version:s.version}))}]}};import{readFileSync as re}from"fs";import{CodePackageType as ie}from"@transcend-io/privacy-types";import se from"js-yaml";import{dirname as ae}from"path";function pe(e){return e.split(`
|
|
2
2
|
`).map(n=>{let o=n.indexOf("#");return o>-1&&!n.substring(0,o).includes('"')&&!n.substring(0,o).includes("'")?n.substring(0,o).trim():n}).filter(n=>n.length>0).join(`
|
|
3
3
|
`)}var v={supportedFiles:["pubspec.yml"],ignoreDirs:["build"],scanFunction:e=>{let n=ae(e),o=re(e,"utf-8"),{name:c,description:a,dev_dependencies:t={},dependencies:p={}}=se.load(pe(o));return[{name:c||n.split("/").pop(),description:a,type:ie.RequirementsTxt,softwareDevelopmentKits:[...Object.entries(p).map(([r,i])=>({name:r,version:typeof i=="string"?i:typeof i=="number"?i.toString():i?.sdk})),...Object.entries(t).map(([r,i])=>({name:r,version:typeof i=="string"?i:typeof i=="number"?i.toString():i?.sdk,isDevDependency:!0}))]}]}};import{readFileSync as ce}from"fs";import{dirname as me}from"path";var I={supportedFiles:["composer.json"],ignoreDirs:["vendor","node_modules","cache","build","dist"],scanFunction:e=>{let n=ce(e,"utf-8"),o=me(e),c=JSON.parse(n),{name:a,description:t,require:p={},"require-dev":r={}}=c;return[{name:a||o.split("/").pop(),description:t,softwareDevelopmentKits:[...Object.entries(p).map(([i,s])=>({name:i,version:typeof s=="string"?s:void 0})),...Object.entries(r).map(([i,s])=>({name:i,version:typeof s=="string"?s:void 0,isDevDependency:!0}))]}]}};import{readFileSync as de}from"fs";import{CodePackageType as ge}from"@transcend-io/privacy-types";import{decodeCodec as fe}from"@transcend-io/type-utils";import*as d from"io-ts";import{dirname as ue}from"path";var le=d.type({pins:d.array(d.type({identity:d.string,kind:d.string,location:d.string,state:d.type({revision:d.string,version:d.string})})),version:d.number}),D={supportedFiles:["Package.resolved"],ignoreDirs:[],scanFunction:e=>{let n=de(e,"utf-8"),o=fe(le,n);return[{name:ue(e).split("/").pop()||"",type:ge.CocoaPods,softwareDevelopmentKits:o.pins.map(c=>({name:c.identity,version:c.state.version}))}]}};import{CodePackageType as f}from"@transcend-io/privacy-types";var gn={cocoaPods:y,gradle:S,javascriptPackageJson:x,pythonRequirementsTxt:P,gemfile:k,pubspec:v,swift:D},_={[f.CocoaPods]:y,[f.Gradle]:S,[f.PackageJson]:x,[f.RequirementsTxt]:P,[f.Gemfile]:k,[f.Pubspec]:v,[f.ComposerJson]:I,[f.Swift]:D};import Ce from"fast-glob";import A from"colors";import{getEntries as Ee}from"@transcend-io/type-utils";async function Sn({scanPath:e,ignoreDirs:n=[],repositoryName:o}){return(await Promise.all(Ee(_).map(async([a,t])=>{let{ignoreDirs:p,supportedFiles:r,scanFunction:i}=t,s=[...n,...p].filter(m=>m.length>0);try{let m=await Ce(`${e}/**/${r.join("|")}`,{ignore:s.map(g=>`${e}/**/${g}`),unique:!0,onlyFiles:!0});E.info(A.magenta(`Scanning: ${m.length} files of type ${a}`));let C=m.map(g=>i(g).map(q=>({...q,relativePath:g.replace(`${e}/`,"")}))).flat();return E.info(A.green(`Found: ${C.length} packages and ${C.map(({softwareDevelopmentKits:g=[]})=>g).flat().length} sdks`)),C.map(g=>({...g,type:a,repositoryName:o}))}catch(m){throw new Error(`Error scanning globs ${r} with error: ${m}`)}}))).flat()}export{gn as a,Sn as b};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_b as S,a as w,f as $,i as B,j as T,l as R}from"./chunk-
|
|
1
|
+
import{_b as S,a as w,f as $,i as B,j as T,l as R}from"./chunk-PDDJKJLS.js";import{a as i}from"./chunk-OERYFLN2.js";import{keyBy as O,uniq as A,chunk as U,sortBy as G}from"lodash-es";import{SubDataPointDataSubCategoryGuessStatus as _}from"@transcend-io/privacy-types";import h from"cli-progress";import{gql as L}from"graphql-request";import f from"colors";async function q(u,{dataSiloIds:e=[],includeGuessedCategories:l,includeAttributes:a,parentCategories:c=[],subCategories:t=[],pageSize:p=1e3}={}){let n=[],m=new Date().getTime(),d=new h.SingleBar({},h.Presets.shades_classic),s={...c.length>0?{category:c}:{},...t.length>0?{subCategoryIds:t}:{},...c.length+t.length>0&&!l?{status:_.Approved}:{},...e.length>0?{dataSilos:e}:{}},{subDataPoints:{totalCount:o}}=await S(u,$,{filterBy:s});i.info(f.magenta("[Step 1/3] Pulling in all subdatapoints")),d.start(o,0);let y=0,D=!1,r,b=0;do try{let{subDataPoints:{nodes:P}}=await S(u,L`
|
|
2
2
|
query TranscendCliSubDataPointCsvExport(
|
|
3
3
|
$filterBy: SubDataPointFiltersInput
|
|
4
4
|
$first: Int!
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{k as i}from"./chunk-
|
|
1
|
+
import{k as i}from"./chunk-HZNRGCLH.js";import o from"inquirer";import m from"inquirer-autocomplete-prompt";async function c({message:e}){let{response:r}=await o.prompt([{name:"response",message:e,type:"confirm"}]);return r}async function l({message:e}){let{response:r}=await o.prompt([{name:"response",message:e,type:"text",validate:t=>t.trim().length>0}]);return r}async function y({defaultValue:e,values:r,message:t}){o.registerPrompt("autocomplete",m);let{response:p}=await o.prompt([{name:"response",message:t,type:"autocomplete",default:e,source:(a,n)=>n?r.filter(s=>typeof s=="string"&&i(n,s)):r}]);return p}export{c as a,l as b,y as c};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{c as _}from"./chunk-RBOBI6B6.js";import{n as A,q as x}from"./chunk-
|
|
1
|
+
import{c as _}from"./chunk-RBOBI6B6.js";import{n as A,q as x}from"./chunk-HZNRGCLH.js";import{Ae as O,Be as D,_ as T,_b as j,b as R,pe as y,qe as E,ye as L}from"./chunk-PDDJKJLS.js";import{a as r}from"./chunk-OERYFLN2.js";import{e as b}from"./chunk-APA5PR4U.js";import{RequestStatus as U}from"@transcend-io/privacy-types";import k from"colors";import{groupBy as G,uniq as Q}from"lodash-es";async function te({file:u,auth:s,sombraAuth:g,requestActions:f=[],concurrency:p=100,transcendUrl:n=b}){let o=y(n,s),e=await E(n,s,g);r.info(k.magenta(`Pulling manual enrichment requests, filtered for actions: ${f.join(",")}`));let d=await L(o,{actions:f,statuses:[U.Enriching]}),i=[];await R(d,async t=>{let c=await D(o,{requestId:t.id});if(c.filter(({status:m})=>m==="ACTION_REQUIRED")){let m=await O(o,e,{requestId:t.id});i.push({...t,requestIdentifiers:m,requestEnrichers:c})}},{concurrency:p});let l=i.map(({attributeValues:t,requestIdentifiers:c,requestEnrichers:I,...m})=>({...m,...Object.entries(G(c,"name")).reduce((w,[P,$])=>Object.assign(w,{[P]:$.map(({value:C})=>C).join(",")}),{}),...Object.entries(G(t,"attributeKey.name")).reduce((w,[P,$])=>Object.assign(w,{[P]:$.map(({name:C})=>C).join(",")}),{})})),a=Q(l.map(t=>Object.keys(t)).flat());return _(u,l,a),r.info(k.green(`Successfully wrote ${i.length} requests to file "${u}"`)),i}import*as q from"io-ts";import{uniq as F}from"lodash-es";import v from"colors";var S="https://app.transcend.io/privacy-requests/incoming-requests/",M=q.record(q.string,q.string);async function N(u,{id:s,...g},f,p){if(!s){let e=`Request ID must be provided to enricher request.${p?` Found error in row: ${p}`:""}`;throw r.error(v.red(e)),new Error(e)}let n=s.toLowerCase(),o=Object.entries(g).reduce((e,[d,i])=>F(A(i)).length===0?e:Object.assign(e,{[d]:F(A(i)).map(a=>({value:d==="email"?a.toLowerCase():a}))}),{});try{return await u.post("v1/enrich-identifiers",{headers:{"x-transcend-request-id":n,"x-transcend-enricher-id":f},json:{enrichedIdentifiers:o}}).json(),r.error(v.green(`Successfully enriched request: ${S}${n}`)),!0}catch(e){if(typeof e.response.body=="string"&&e.response.body.includes("Cannot update a resolved RequestEnricher"))return r.warn(v.magenta(`Skipped enrichment for request: ${S}${n}, request is no longer in the enriching phase.`)),!1;throw r.error(v.red(`Failed to enricher identifiers for request with id: ${S}${n} - ${e.message} - ${e.response.body}`)),e}}import h from"colors";async function ge({file:u,auth:s,sombraAuth:g,enricherId:f,markSilent:p,concurrency:n=100,transcendUrl:o=b}){let e=await E(o,s,g),d=y(o,s);r.info(h.magenta(`Reading "${u}" from disk`));let i=x(u,M);r.info(h.magenta(`Enriching "${i.length}" privacy requests.`));let l=0,a=0,t=0;if(await R(i,async(c,I)=>{try{p&&(await j(d,T,{input:{id:c.id,isSilent:!0}}),r.info(h.magenta(`Mark request as silent mode - ${c.id}`))),await N(e,c,f,I)?l+=1:a+=1}catch{t+=1}},{concurrency:n}),r.info(h.green(`Successfully notified Transcend!
|
|
2
2
|
Success count: ${l}.`)),a>0&&r.info(h.magenta(`Skipped count: ${a}.`)),t>0)throw r.info(h.red(`Error Count: ${t}.`)),new Error(`Failed to enrich: ${t} requests.`);return i.length}export{te as a,M as b,N as c,ge as d};
|