@transcend-io/cli 6.23.1 → 6.25.0
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 +154 -32
- package/build/cli-request-download-files.d.ts +3 -0
- package/build/cli-request-download-files.d.ts.map +1 -0
- package/build/cli-request-download-files.js +77 -0
- package/build/cli-request-download-files.js.map +1 -0
- package/build/cli-skip-preflight-jobs.d.ts +3 -0
- package/build/cli-skip-preflight-jobs.d.ts.map +1 -0
- package/build/cli-skip-preflight-jobs.js +53 -0
- package/build/cli-skip-preflight-jobs.js.map +1 -0
- package/build/codecs.d.ts +8 -0
- package/build/codecs.d.ts.map +1 -1
- package/build/graphql/fetchAllPrivacyCenters.d.ts +0 -2
- package/build/graphql/fetchAllPrivacyCenters.d.ts.map +1 -1
- package/build/graphql/fetchAllPrivacyCenters.js.map +1 -1
- package/build/graphql/fetchAllRequests.d.ts +6 -1
- package/build/graphql/fetchAllRequests.d.ts.map +1 -1
- package/build/graphql/fetchAllRequests.js +9 -2
- package/build/graphql/fetchAllRequests.js.map +1 -1
- package/build/graphql/fetchConsentManagerId.d.ts +0 -8
- package/build/graphql/fetchConsentManagerId.d.ts.map +1 -1
- package/build/graphql/fetchConsentManagerId.js.map +1 -1
- package/build/graphql/gqls/RequestEnricher.d.ts +1 -0
- package/build/graphql/gqls/RequestEnricher.d.ts.map +1 -1
- package/build/graphql/gqls/RequestEnricher.js +10 -1
- package/build/graphql/gqls/RequestEnricher.js.map +1 -1
- package/build/graphql/gqls/privacyCenter.d.ts.map +1 -1
- package/build/graphql/gqls/privacyCenter.js +0 -1
- package/build/graphql/gqls/privacyCenter.js.map +1 -1
- package/build/graphql/pullTranscendConfiguration.d.ts.map +1 -1
- package/build/graphql/pullTranscendConfiguration.js +0 -1
- package/build/graphql/pullTranscendConfiguration.js.map +1 -1
- package/build/graphql/syncPrivacyCenter.d.ts.map +1 -1
- package/build/graphql/syncPrivacyCenter.js +0 -3
- package/build/graphql/syncPrivacyCenter.js.map +1 -1
- package/build/preference-management/codecs.d.ts +22 -4
- package/build/preference-management/codecs.d.ts.map +1 -1
- package/build/requests/bulkRestartRequests.d.ts.map +1 -1
- package/build/requests/bulkRestartRequests.js +1 -3
- package/build/requests/bulkRestartRequests.js.map +1 -1
- package/build/requests/bulkRetryEnrichers.d.ts.map +1 -1
- package/build/requests/bulkRetryEnrichers.js +2 -3
- package/build/requests/bulkRetryEnrichers.js.map +1 -1
- package/build/requests/cancelPrivacyRequests.d.ts.map +1 -1
- package/build/requests/cancelPrivacyRequests.js +2 -5
- package/build/requests/cancelPrivacyRequests.js.map +1 -1
- package/build/requests/downloadPrivacyRequestFiles.d.ts +30 -0
- package/build/requests/downloadPrivacyRequestFiles.d.ts.map +1 -0
- package/build/requests/downloadPrivacyRequestFiles.js +96 -0
- package/build/requests/downloadPrivacyRequestFiles.js.map +1 -0
- package/build/requests/getFileMetadataForPrivacyRequests.d.ts +157 -0
- package/build/requests/getFileMetadataForPrivacyRequests.d.ts.map +1 -0
- package/build/requests/getFileMetadataForPrivacyRequests.js +159 -0
- package/build/requests/getFileMetadataForPrivacyRequests.js.map +1 -0
- package/build/requests/index.d.ts +4 -0
- package/build/requests/index.d.ts.map +1 -1
- package/build/requests/index.js +4 -0
- package/build/requests/index.js.map +1 -1
- package/build/requests/markSilentPrivacyRequests.d.ts.map +1 -1
- package/build/requests/markSilentPrivacyRequests.js +2 -5
- package/build/requests/markSilentPrivacyRequests.js.map +1 -1
- package/build/requests/notifyPrivacyRequestsAdditionalTime.d.ts.map +1 -1
- package/build/requests/notifyPrivacyRequestsAdditionalTime.js +1 -4
- package/build/requests/notifyPrivacyRequestsAdditionalTime.js.map +1 -1
- package/build/requests/skipPreflightJobs.d.ts +20 -0
- package/build/requests/skipPreflightJobs.d.ts.map +1 -0
- package/build/requests/skipPreflightJobs.js +73 -0
- package/build/requests/skipPreflightJobs.js.map +1 -0
- package/build/requests/streamPrivacyRequestFiles.d.ts +22 -0
- package/build/requests/streamPrivacyRequestFiles.d.ts.map +1 -0
- package/build/requests/streamPrivacyRequestFiles.js +48 -0
- package/build/requests/streamPrivacyRequestFiles.js.map +1 -0
- package/build/tsbuildinfo +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skipPreflightJobs.d.ts","sourceRoot":"","sources":["../../src/requests/skipPreflightJobs.ts"],"names":[],"mappings":"AAWA,OAAO,EAEL,aAAa,EACd,MAAM,6BAA6B,CAAC;AAGrC;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,WAAW,EACX,IAAI,EACJ,WAAiB,EACjB,YAAoC,GACrC,EAAE;IACD,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC;CACnC,GAAG,OAAO,CAAC,MAAM,CAAC,CAuFlB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.skipPreflightJobs = void 0;
|
|
7
|
+
const bluebird_1 = require("bluebird");
|
|
8
|
+
const colors_1 = __importDefault(require("colors"));
|
|
9
|
+
const logger_1 = require("../logger");
|
|
10
|
+
const graphql_1 = require("../graphql");
|
|
11
|
+
const cli_progress_1 = __importDefault(require("cli-progress"));
|
|
12
|
+
const privacy_types_1 = require("@transcend-io/privacy-types");
|
|
13
|
+
const constants_1 = require("../constants");
|
|
14
|
+
/**
|
|
15
|
+
* Given an enricher ID, mark all open request enrichers as skipped
|
|
16
|
+
*
|
|
17
|
+
* @param options - Options
|
|
18
|
+
* @returns Number of items skipped
|
|
19
|
+
*/
|
|
20
|
+
async function skipPreflightJobs({ enricherIds, auth, concurrency = 100, transcendUrl = constants_1.DEFAULT_TRANSCEND_API, }) {
|
|
21
|
+
// Find all requests made before createdAt that are in a removing data state
|
|
22
|
+
const client = (0, graphql_1.buildTranscendGraphQLClient)(transcendUrl, auth);
|
|
23
|
+
// Time duration
|
|
24
|
+
const t0 = new Date().getTime();
|
|
25
|
+
// fetch all RequestDataSilos that are open
|
|
26
|
+
const requests = await (0, graphql_1.fetchAllRequests)(client, {
|
|
27
|
+
statuses: [privacy_types_1.RequestStatus.Enriching],
|
|
28
|
+
});
|
|
29
|
+
// Notify Transcend
|
|
30
|
+
logger_1.logger.info(colors_1.default.magenta(`Processing enricher: "${enricherIds.join(',')}" fetched "${requests.length}" in enriching status.`));
|
|
31
|
+
// create a new progress bar instance and use shades_classic theme
|
|
32
|
+
const progressBar = new cli_progress_1.default.SingleBar({}, cli_progress_1.default.Presets.shades_classic);
|
|
33
|
+
let total = 0;
|
|
34
|
+
progressBar.start(requests.length, 0);
|
|
35
|
+
let totalSkipped = 0;
|
|
36
|
+
await (0, bluebird_1.map)(requests, async (request) => {
|
|
37
|
+
// FIXME dont pull all in
|
|
38
|
+
const requestEnrichers = await (0, graphql_1.fetchAllRequestEnrichers)(client, {
|
|
39
|
+
requestId: request.id,
|
|
40
|
+
});
|
|
41
|
+
const requestEnrichersFiltered = requestEnrichers.filter((enricher) => enricherIds.includes(enricher.enricher.id) &&
|
|
42
|
+
![
|
|
43
|
+
privacy_types_1.RequestEnricherStatus.Resolved,
|
|
44
|
+
privacy_types_1.RequestEnricherStatus.Skipped,
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
|
+
].includes(enricher.status));
|
|
47
|
+
// FIXME
|
|
48
|
+
if (requestEnrichersFiltered.length > 0) {
|
|
49
|
+
await (0, bluebird_1.mapSeries)(requestEnrichersFiltered, async (requestEnricher) => {
|
|
50
|
+
try {
|
|
51
|
+
await (0, graphql_1.makeGraphQLRequest)(client, graphql_1.SKIP_REQUEST_ENRICHER, {
|
|
52
|
+
requestEnricherId: requestEnricher.id,
|
|
53
|
+
});
|
|
54
|
+
totalSkipped += 1;
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
if (!err.message.includes('Client error: Cannot skip Request enricher because it has already completed')) {
|
|
58
|
+
throw err;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
total += 1;
|
|
64
|
+
progressBar.update(total);
|
|
65
|
+
}, { concurrency });
|
|
66
|
+
progressBar.stop();
|
|
67
|
+
const t1 = new Date().getTime();
|
|
68
|
+
const totalTime = t1 - t0;
|
|
69
|
+
logger_1.logger.info(colors_1.default.green(`Successfully skipped "${totalSkipped}" for "${requests.length}" requests in "${totalTime / 1000}" seconds!`));
|
|
70
|
+
return requests.length;
|
|
71
|
+
}
|
|
72
|
+
exports.skipPreflightJobs = skipPreflightJobs;
|
|
73
|
+
//# sourceMappingURL=skipPreflightJobs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skipPreflightJobs.js","sourceRoot":"","sources":["../../src/requests/skipPreflightJobs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { RequestFileMetadata } from './getFileMetadataForPrivacyRequests';
|
|
3
|
+
import { Got } from 'got/dist/source';
|
|
4
|
+
/**
|
|
5
|
+
* This function will take in a set of file metadata for privacy requests
|
|
6
|
+
* call the Transcend API to stream the file metadata for these requests
|
|
7
|
+
* and pass that through a callback function
|
|
8
|
+
*
|
|
9
|
+
* @param fileMetadata - Metadata to download
|
|
10
|
+
* @param options - Options for the request
|
|
11
|
+
*/
|
|
12
|
+
export declare function streamPrivacyRequestFiles(fileMetadata: RequestFileMetadata[], { requestId, sombra, onFileDownloaded, concurrency, }: {
|
|
13
|
+
/** Request ID for logging */
|
|
14
|
+
requestId: string;
|
|
15
|
+
/** Sombra got instance */
|
|
16
|
+
sombra: Got;
|
|
17
|
+
/** Handler on each file */
|
|
18
|
+
onFileDownloaded: (metadata: RequestFileMetadata, stream: Buffer) => void;
|
|
19
|
+
/** Concurrent downloads at once */
|
|
20
|
+
concurrency?: number;
|
|
21
|
+
}): Promise<void>;
|
|
22
|
+
//# sourceMappingURL=streamPrivacyRequestFiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamPrivacyRequestFiles.d.ts","sourceRoot":"","sources":["../../src/requests/streamPrivacyRequestFiles.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAGtC;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,YAAY,EAAE,mBAAmB,EAAE,EACnC,EACE,SAAS,EACT,MAAM,EACN,gBAAgB,EAChB,WAAgB,GACjB,EAAE;IACD,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,MAAM,EAAE,GAAG,CAAC;IACZ,2BAA2B;IAC3B,gBAAgB,EAAE,CAAC,QAAQ,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1E,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACA,OAAO,CAAC,IAAI,CAAC,CAsCf"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.streamPrivacyRequestFiles = void 0;
|
|
7
|
+
const bluebird_1 = require("bluebird");
|
|
8
|
+
const colors_1 = __importDefault(require("colors"));
|
|
9
|
+
const logger_1 = require("../logger");
|
|
10
|
+
/**
|
|
11
|
+
* This function will take in a set of file metadata for privacy requests
|
|
12
|
+
* call the Transcend API to stream the file metadata for these requests
|
|
13
|
+
* and pass that through a callback function
|
|
14
|
+
*
|
|
15
|
+
* @param fileMetadata - Metadata to download
|
|
16
|
+
* @param options - Options for the request
|
|
17
|
+
*/
|
|
18
|
+
async function streamPrivacyRequestFiles(fileMetadata, { requestId, sombra, onFileDownloaded, concurrency = 20, }) {
|
|
19
|
+
// Loop over each file
|
|
20
|
+
await (0, bluebird_1.map)(fileMetadata, async (metadata) => {
|
|
21
|
+
var _a, _b, _c;
|
|
22
|
+
try {
|
|
23
|
+
// Construct the stream
|
|
24
|
+
await sombra
|
|
25
|
+
.get('v1/files', {
|
|
26
|
+
searchParams: {
|
|
27
|
+
downloadKey: metadata.downloadKey,
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
.buffer()
|
|
31
|
+
.then((fileResponse) => onFileDownloaded(metadata, fileResponse));
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
if ((_b = (_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.includes('fileMetadata#verify')) {
|
|
35
|
+
logger_1.logger.error(colors_1.default.red(`Failed to pull file for: ${metadata.fileName} (request:${requestId}) - JWT expired. ` +
|
|
36
|
+
'This likely means that the file is no longer available. ' +
|
|
37
|
+
'Try restarting the request from scratch in Transcend Admin Dashboard. ' +
|
|
38
|
+
'Skipping the download of this file.'));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
throw new Error(`Received an error from server: ${((_c = err === null || err === void 0 ? void 0 : err.response) === null || _c === void 0 ? void 0 : _c.body) || (err === null || err === void 0 ? void 0 : err.message)}`);
|
|
42
|
+
}
|
|
43
|
+
}, {
|
|
44
|
+
concurrency,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
exports.streamPrivacyRequestFiles = streamPrivacyRequestFiles;
|
|
48
|
+
//# sourceMappingURL=streamPrivacyRequestFiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamPrivacyRequestFiles.js","sourceRoot":"","sources":["../../src/requests/streamPrivacyRequestFiles.ts"],"names":[],"mappings":";;;;;;AAAA,uCAA+B;AAC/B,oDAA4B;AAG5B,sCAAmC;AAEnC;;;;;;;GAOG;AACI,KAAK,UAAU,yBAAyB,CAC7C,YAAmC,EACnC,EACE,SAAS,EACT,MAAM,EACN,gBAAgB,EAChB,WAAW,GAAG,EAAE,GAUjB;IAED,sBAAsB;IACtB,MAAM,IAAA,cAAG,EACP,YAAY,EACZ,KAAK,EAAE,QAAQ,EAAE,EAAE;;QACjB,IAAI;YACF,uBAAuB;YACvB,MAAM,MAAM;iBACT,GAAG,CAAC,UAAU,EAAE;gBACf,YAAY,EAAE;oBACZ,WAAW,EAAE,QAAQ,CAAC,WAAW;iBAClC;aACF,CAAC;iBACD,MAAM,EAAE;iBACR,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;SACrE;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,MAAA,MAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,QAAQ,0CAAE,IAAI,0CAAE,QAAQ,CAAC,qBAAqB,CAAC,EAAE;gBACxD,eAAM,CAAC,KAAK,CACV,gBAAM,CAAC,GAAG,CACR,4BAA4B,QAAQ,CAAC,QAAQ,aAAa,SAAS,mBAAmB;oBACpF,0DAA0D;oBAC1D,wEAAwE;oBACxE,qCAAqC,CACxC,CACF,CAAC;gBACF,OAAO;aACR;YACD,MAAM,IAAI,KAAK,CACb,kCACE,CAAA,MAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,QAAQ,0CAAE,IAAI,MAAI,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,OAAO,CACrC,EAAE,CACH,CAAC;SACH;IACH,CAAC,EACD;QACE,WAAW;KACZ,CACF,CAAC;AACJ,CAAC;AAvDD,8DAuDC"}
|