@transcend-io/sdk 0.0.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/dist/index.d.mts +256 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +377 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +48 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { Logger } from "@transcend-io/utils";
|
|
2
|
+
import { GraphQLClient, RequestDocument, Variables } from "graphql-request";
|
|
3
|
+
import { Got } from "got";
|
|
4
|
+
import { DefaultConsentOption, IdentifierType, PreferenceStoreAuthLevel, PreferenceTopicType, RequestAction, SombraStandardScope } from "@transcend-io/privacy-types";
|
|
5
|
+
import { UserPrivacySignalEnum } from "@transcend-io/airgap.js-types";
|
|
6
|
+
|
|
7
|
+
//#region src/api/buildTranscendGraphQLClient.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* Create a GraphQL client
|
|
10
|
+
*
|
|
11
|
+
* @param transcendUrl - Transcend API URL
|
|
12
|
+
* @param headers - Request headers to include in each request
|
|
13
|
+
* @param version - Optional version string to include in request headers
|
|
14
|
+
* @returns GraphQL client
|
|
15
|
+
*/
|
|
16
|
+
declare function buildTranscendGraphQLClientGeneric(transcendUrl: string, headers: Record<string, string>, version?: string): GraphQLClient;
|
|
17
|
+
/**
|
|
18
|
+
* Create a GraphQL client capable of submitting requests with an API key
|
|
19
|
+
*
|
|
20
|
+
* @param transcendUrl - Transcend API URL
|
|
21
|
+
* @param auth - API key to authenticate to API
|
|
22
|
+
* @param version - Optional version string to include in request headers
|
|
23
|
+
* @returns GraphQL client
|
|
24
|
+
*/
|
|
25
|
+
declare function buildTranscendGraphQLClient(transcendUrl: string, auth: string, version?: string): GraphQLClient;
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/api/makeGraphQLRequest.d.ts
|
|
28
|
+
/**
|
|
29
|
+
* Make a GraphQL request with retries
|
|
30
|
+
*
|
|
31
|
+
* @param client - GraphQL client
|
|
32
|
+
* @param document - GraphQL document
|
|
33
|
+
* @param options - Options including logger, variables, headers, and retry config
|
|
34
|
+
* @returns Response
|
|
35
|
+
*/
|
|
36
|
+
declare function makeGraphQLRequest<T, V extends Variables = Variables>(client: GraphQLClient, document: RequestDocument, options: {
|
|
37
|
+
/** GraphQL variables */variables?: V; /** Logger for retry/error messages */
|
|
38
|
+
logger: Logger; /** Additional request headers */
|
|
39
|
+
requestHeaders?: Record<string, string> | string[][] | Headers; /** Max number of retry attempts (default 4) */
|
|
40
|
+
maxRetries?: number;
|
|
41
|
+
}): Promise<T>;
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/api/createSombraGotInstance.d.ts
|
|
44
|
+
/**
|
|
45
|
+
* Instantiate an instance of got that is capable of making requests
|
|
46
|
+
* to a sombra gateway.
|
|
47
|
+
*
|
|
48
|
+
* @param transcendUrl - URL of Transcend API
|
|
49
|
+
* @param transcendApiKey - Transcend API key
|
|
50
|
+
* @param options - Additional options
|
|
51
|
+
* @returns The instance of got that is capable of making requests to the customer ingress
|
|
52
|
+
*/
|
|
53
|
+
declare function createSombraGotInstance(transcendUrl: string, transcendApiKey: string, options: {
|
|
54
|
+
/** Logger instance */logger: Logger; /** Sombra API key */
|
|
55
|
+
sombraApiKey?: string; /** Override Sombra URL (replaces process.env.SOMBRA_URL lookup) */
|
|
56
|
+
sombraUrl?: string;
|
|
57
|
+
}): Promise<Got>;
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/data-inventory/fetchAllIdentifiers.d.ts
|
|
60
|
+
interface Identifier {
|
|
61
|
+
/** ID of identifier */
|
|
62
|
+
id: string;
|
|
63
|
+
/** Name of identifier */
|
|
64
|
+
name: string;
|
|
65
|
+
/** The type of identifier */
|
|
66
|
+
type: IdentifierType;
|
|
67
|
+
/** Regular expression */
|
|
68
|
+
regex: string;
|
|
69
|
+
/** The set of options that the identifier supports */
|
|
70
|
+
selectOptions: string[];
|
|
71
|
+
/** Whether identifier is enabled on privacy center */
|
|
72
|
+
privacyCenterVisibility: RequestAction[];
|
|
73
|
+
/** Enabled data subjects that are exposed this identifier on the privacy center */
|
|
74
|
+
dataSubjects: {
|
|
75
|
+
type: string;
|
|
76
|
+
}[];
|
|
77
|
+
/** Whether identifier is a required field in privacy center form */
|
|
78
|
+
isRequiredInForm: boolean;
|
|
79
|
+
/** Identifier placeholder text */
|
|
80
|
+
placeholder: string;
|
|
81
|
+
/** Display title for identifier */
|
|
82
|
+
displayTitle: {
|
|
83
|
+
defaultMessage: string;
|
|
84
|
+
};
|
|
85
|
+
/** Display description for identifier */
|
|
86
|
+
displayDescription: {
|
|
87
|
+
defaultMessage: string;
|
|
88
|
+
};
|
|
89
|
+
/** Display order */
|
|
90
|
+
displayOrder: number;
|
|
91
|
+
/** Does this identifier uniquely identify a consent record */
|
|
92
|
+
isUniqueOnPreferenceStore: boolean;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Fetch all identifiers in the organization
|
|
96
|
+
*
|
|
97
|
+
* @param client - GraphQL client
|
|
98
|
+
* @param options - Options
|
|
99
|
+
* @returns All identifiers in the organization
|
|
100
|
+
*/
|
|
101
|
+
declare function fetchAllIdentifiers(client: GraphQLClient, options: {
|
|
102
|
+
logger: Logger;
|
|
103
|
+
}): Promise<Identifier[]>;
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/preference-management/fetchAllPurposes.d.ts
|
|
106
|
+
interface Purpose {
|
|
107
|
+
/** ID of purpose */
|
|
108
|
+
id: string;
|
|
109
|
+
/** Name of purpose */
|
|
110
|
+
name: string;
|
|
111
|
+
/** Description of purpose */
|
|
112
|
+
description: string;
|
|
113
|
+
/** Default consent status */
|
|
114
|
+
defaultConsent: DefaultConsentOption;
|
|
115
|
+
/** Slug of purpose */
|
|
116
|
+
trackingType: string;
|
|
117
|
+
/** Whether the purpose is configurable */
|
|
118
|
+
configurable: boolean;
|
|
119
|
+
/** Whether the purpose is essential */
|
|
120
|
+
essential: boolean;
|
|
121
|
+
/** Whether to show the purpose in the consent manager */
|
|
122
|
+
showInConsentManager: boolean;
|
|
123
|
+
/** Whether the purpose is active */
|
|
124
|
+
isActive: boolean;
|
|
125
|
+
/** Display order of the purpose */
|
|
126
|
+
displayOrder: number;
|
|
127
|
+
/** Opt-out signals for the purpose */
|
|
128
|
+
optOutSignals: UserPrivacySignalEnum[];
|
|
129
|
+
/** Whether the purpose is deleted */
|
|
130
|
+
deletedAt?: string;
|
|
131
|
+
/** Authorization level required for the purpose */
|
|
132
|
+
authLevel: PreferenceStoreAuthLevel;
|
|
133
|
+
/** Whether to show the purpose in the privacy center */
|
|
134
|
+
showInPrivacyCenter: boolean;
|
|
135
|
+
/** Title of the purpose */
|
|
136
|
+
title: string;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Fetch all purposes in the organization
|
|
140
|
+
*
|
|
141
|
+
* @param client - GraphQL client
|
|
142
|
+
* @param options - Options
|
|
143
|
+
* @returns All purposes in the organization
|
|
144
|
+
*/
|
|
145
|
+
declare function fetchAllPurposes(client: GraphQLClient, options: {
|
|
146
|
+
/** Logger instance */logger: Logger; /** Whether to include deleted purposes */
|
|
147
|
+
includeDeleted?: boolean;
|
|
148
|
+
}): Promise<Purpose[]>;
|
|
149
|
+
//#endregion
|
|
150
|
+
//#region src/preference-management/fetchAllPreferenceTopics.d.ts
|
|
151
|
+
interface PreferenceTopic {
|
|
152
|
+
/** ID of preference topic */
|
|
153
|
+
id: string;
|
|
154
|
+
/** Slug of preference topic */
|
|
155
|
+
slug: string;
|
|
156
|
+
/** Title of topic */
|
|
157
|
+
title: {
|
|
158
|
+
id: string; /** Default message */
|
|
159
|
+
defaultMessage: string;
|
|
160
|
+
};
|
|
161
|
+
/** Whether to show in privacy center */
|
|
162
|
+
showInPrivacyCenter: boolean;
|
|
163
|
+
/** Description to display in privacy center */
|
|
164
|
+
displayDescription: {
|
|
165
|
+
id: string; /** Default message */
|
|
166
|
+
defaultMessage: string;
|
|
167
|
+
};
|
|
168
|
+
/** Type of preference topic */
|
|
169
|
+
type: PreferenceTopicType;
|
|
170
|
+
/** Default configuration */
|
|
171
|
+
defaultConfiguration: string;
|
|
172
|
+
/** Option values */
|
|
173
|
+
preferenceOptionValues: {
|
|
174
|
+
/** Slug of value */slug: string; /** Title of value */
|
|
175
|
+
title: {
|
|
176
|
+
id: string; /** Default message */
|
|
177
|
+
defaultMessage: string;
|
|
178
|
+
};
|
|
179
|
+
}[];
|
|
180
|
+
/** Related purpose */
|
|
181
|
+
purpose: {
|
|
182
|
+
trackingType: string;
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Fetch all preference topics in the organization
|
|
187
|
+
*
|
|
188
|
+
* @param client - GraphQL client
|
|
189
|
+
* @param options - Options
|
|
190
|
+
* @returns All preference topics in the organization
|
|
191
|
+
*/
|
|
192
|
+
declare function fetchAllPreferenceTopics(client: GraphQLClient, options: {
|
|
193
|
+
/** Logger instance */logger: Logger;
|
|
194
|
+
}): Promise<PreferenceTopic[]>;
|
|
195
|
+
//#endregion
|
|
196
|
+
//#region src/preference-management/fetchAllPurposesAndPreferences.d.ts
|
|
197
|
+
interface PurposeWithPreferences extends Purpose {
|
|
198
|
+
/** Topics */
|
|
199
|
+
topics: PreferenceTopic[];
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Fetch all purposes and preferences
|
|
203
|
+
*
|
|
204
|
+
* @param client - GraphQL client
|
|
205
|
+
* @param options - Options
|
|
206
|
+
* @returns List of purposes with their preference topics
|
|
207
|
+
*/
|
|
208
|
+
declare function fetchAllPurposesAndPreferences(client: GraphQLClient, options: {
|
|
209
|
+
logger: Logger;
|
|
210
|
+
}): Promise<PurposeWithPreferences[]>;
|
|
211
|
+
//#endregion
|
|
212
|
+
//#region src/preference-management/createPreferenceAccessTokens.d.ts
|
|
213
|
+
interface PreferenceAccessTokenInput {
|
|
214
|
+
/** Slug of data subject to authenticate as */
|
|
215
|
+
subjectType: string;
|
|
216
|
+
/** Scopes to grant */
|
|
217
|
+
scopes: SombraStandardScope[];
|
|
218
|
+
/** Expiration time in seconds */
|
|
219
|
+
expiresIn?: number;
|
|
220
|
+
/** Email address of user */
|
|
221
|
+
email: string;
|
|
222
|
+
/** Core identifier for the user */
|
|
223
|
+
coreIdentifier?: string;
|
|
224
|
+
}
|
|
225
|
+
interface PreferenceAccessTokenInputWithIndex extends PreferenceAccessTokenInput {
|
|
226
|
+
/** Index of the input record */
|
|
227
|
+
index?: number;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Create preference access tokens for the given identifiers.
|
|
231
|
+
*
|
|
232
|
+
* @see https://docs.transcend.io/docs/articles/preference-management/access-links
|
|
233
|
+
* @param client - GraphQL client
|
|
234
|
+
* @param options - Options
|
|
235
|
+
* @returns list of access tokens/input identifiers
|
|
236
|
+
*/
|
|
237
|
+
declare function createPreferenceAccessTokens(client: GraphQLClient, options: {
|
|
238
|
+
/** Records to create tokens for */records: PreferenceAccessTokenInputWithIndex[]; /** Logger instance */
|
|
239
|
+
logger: Logger; /** Optional progress emitter */
|
|
240
|
+
emitProgress?: (progress: number) => void; /** Number of concurrent requests to make (default: 10) */
|
|
241
|
+
concurrency?: number;
|
|
242
|
+
}): Promise<{
|
|
243
|
+
/** Identifier for the record */input: PreferenceAccessTokenInputWithIndex; /** Access token */
|
|
244
|
+
accessToken: string;
|
|
245
|
+
}[]>;
|
|
246
|
+
//#endregion
|
|
247
|
+
//#region src/index.d.ts
|
|
248
|
+
interface MonorepoPackageDefinition {
|
|
249
|
+
directory: string;
|
|
250
|
+
displayName: string;
|
|
251
|
+
packageName: string;
|
|
252
|
+
}
|
|
253
|
+
declare function createMonorepoPackageDefinition(name: string, directory: string): MonorepoPackageDefinition;
|
|
254
|
+
//#endregion
|
|
255
|
+
export { Identifier, MonorepoPackageDefinition, PreferenceAccessTokenInput, PreferenceAccessTokenInputWithIndex, PreferenceTopic, Purpose, PurposeWithPreferences, buildTranscendGraphQLClient, buildTranscendGraphQLClientGeneric, createMonorepoPackageDefinition, createPreferenceAccessTokens, createSombraGotInstance, fetchAllIdentifiers, fetchAllPreferenceTopics, fetchAllPurposes, fetchAllPurposesAndPreferences, makeGraphQLRequest };
|
|
256
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/api/buildTranscendGraphQLClient.ts","../src/api/makeGraphQLRequest.ts","../src/api/createSombraGotInstance.ts","../src/data-inventory/fetchAllIdentifiers.ts","../src/preference-management/fetchAllPurposes.ts","../src/preference-management/fetchAllPreferenceTopics.ts","../src/preference-management/fetchAllPurposesAndPreferences.ts","../src/preference-management/createPreferenceAccessTokens.ts","../src/index.ts"],"mappings":"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"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { describePackageName, map, sleepPromise } from "@transcend-io/utils";
|
|
2
|
+
import { GraphQLClient, gql } from "graphql-request";
|
|
3
|
+
import got from "got";
|
|
4
|
+
import { parse } from "graphql";
|
|
5
|
+
import { chunk } from "lodash-es";
|
|
6
|
+
//#region src/api/buildTranscendGraphQLClient.ts
|
|
7
|
+
/**
|
|
8
|
+
* Create a GraphQL client
|
|
9
|
+
*
|
|
10
|
+
* @param transcendUrl - Transcend API URL
|
|
11
|
+
* @param headers - Request headers to include in each request
|
|
12
|
+
* @param version - Optional version string to include in request headers
|
|
13
|
+
* @returns GraphQL client
|
|
14
|
+
*/
|
|
15
|
+
function buildTranscendGraphQLClientGeneric(transcendUrl, headers, version) {
|
|
16
|
+
return new GraphQLClient(`${transcendUrl}/graphql`, { headers: {
|
|
17
|
+
...headers,
|
|
18
|
+
...version ? { version } : {}
|
|
19
|
+
} });
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Create a GraphQL client capable of submitting requests with an API key
|
|
23
|
+
*
|
|
24
|
+
* @param transcendUrl - Transcend API URL
|
|
25
|
+
* @param auth - API key to authenticate to API
|
|
26
|
+
* @param version - Optional version string to include in request headers
|
|
27
|
+
* @returns GraphQL client
|
|
28
|
+
*/
|
|
29
|
+
function buildTranscendGraphQLClient(transcendUrl, auth, version) {
|
|
30
|
+
return buildTranscendGraphQLClientGeneric(transcendUrl, { Authorization: `Bearer ${auth}` }, version);
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/api/makeGraphQLRequest.ts
|
|
34
|
+
const DEFAULT_MAX_RETRIES = 4;
|
|
35
|
+
const KNOWN_ERRORS = [
|
|
36
|
+
"syntax error",
|
|
37
|
+
"got invalid value",
|
|
38
|
+
"Client error",
|
|
39
|
+
"cannot affect row a second time",
|
|
40
|
+
"GRAPHQL_VALIDATION_FAILED"
|
|
41
|
+
];
|
|
42
|
+
/**
|
|
43
|
+
* Make a GraphQL request with retries
|
|
44
|
+
*
|
|
45
|
+
* @param client - GraphQL client
|
|
46
|
+
* @param document - GraphQL document
|
|
47
|
+
* @param options - Options including logger, variables, headers, and retry config
|
|
48
|
+
* @returns Response
|
|
49
|
+
*/
|
|
50
|
+
async function makeGraphQLRequest(client, document, options) {
|
|
51
|
+
const { variables, logger, requestHeaders, maxRetries = DEFAULT_MAX_RETRIES } = options;
|
|
52
|
+
let retryCount = 0;
|
|
53
|
+
while (true) try {
|
|
54
|
+
return await client.request(document, variables, requestHeaders);
|
|
55
|
+
} catch (err) {
|
|
56
|
+
if (err.message?.includes("API key is invalid")) throw new Error("API key is invalid. Please ensure that the key provided has the proper scope and is not expired, and that the transcendUrl corresponds to the correct backend for your organization.");
|
|
57
|
+
if (KNOWN_ERRORS.some((msg) => err.message?.includes(msg))) throw err;
|
|
58
|
+
if (err.message?.startsWith("Client error: Too many requests")) {
|
|
59
|
+
const rateLimitResetAt = err.response?.headers?.get("x-ratelimit-reset");
|
|
60
|
+
const sleepTime = rateLimitResetAt ? new Date(rateLimitResetAt).getTime() - (/* @__PURE__ */ new Date()).getTime() + 100 : 1e3 * 10;
|
|
61
|
+
logger.warn(`DETECTED RATE LIMIT: ${err.message}. Sleeping for ${sleepTime}ms`);
|
|
62
|
+
await sleepPromise(sleepTime);
|
|
63
|
+
}
|
|
64
|
+
if (retryCount >= maxRetries) throw err;
|
|
65
|
+
retryCount += 1;
|
|
66
|
+
logger.warn(`Retrying failed request (${retryCount} / ${maxRetries}): ${err.message}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/api/gqls/organization.ts
|
|
71
|
+
const ORGANIZATION = parse(gql`
|
|
72
|
+
query TranscendCliOrganization {
|
|
73
|
+
organization {
|
|
74
|
+
sombra {
|
|
75
|
+
customerUrl
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
`);
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/api/createSombraGotInstance.ts
|
|
82
|
+
/**
|
|
83
|
+
* Instantiate an instance of got that is capable of making requests
|
|
84
|
+
* to a sombra gateway.
|
|
85
|
+
*
|
|
86
|
+
* @param transcendUrl - URL of Transcend API
|
|
87
|
+
* @param transcendApiKey - Transcend API key
|
|
88
|
+
* @param options - Additional options
|
|
89
|
+
* @returns The instance of got that is capable of making requests to the customer ingress
|
|
90
|
+
*/
|
|
91
|
+
async function createSombraGotInstance(transcendUrl, transcendApiKey, options) {
|
|
92
|
+
const { logger, sombraApiKey, sombraUrl } = options;
|
|
93
|
+
const { organization } = await makeGraphQLRequest(buildTranscendGraphQLClient(transcendUrl, transcendApiKey), ORGANIZATION, { logger });
|
|
94
|
+
const { customerUrl } = organization.sombra;
|
|
95
|
+
const sombraToUse = sombraUrl || customerUrl;
|
|
96
|
+
if (!sombraUrl && ["https://sombra-reverse-tunnel.transcend.io", "https://sombra-reverse-tunnel.us.transcend.io"].includes(customerUrl)) throw new Error("It looks like your Sombra customer ingress URL has not been set up. Please follow the instructions here to configure networking for Sombra: https://docs.transcend.io/docs/articles/sombra/deploying/customizing-sombra/networking");
|
|
97
|
+
logger.info(`Using sombra: ${sombraToUse}`);
|
|
98
|
+
return got.extend({
|
|
99
|
+
prefixUrl: sombraToUse,
|
|
100
|
+
headers: {
|
|
101
|
+
Authorization: `Bearer ${transcendApiKey}`,
|
|
102
|
+
...sombraApiKey ? { "X-Sombra-Authorization": `Bearer ${sombraApiKey}` } : {}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
//#endregion
|
|
107
|
+
//#region src/data-inventory/gqls/identifier.ts
|
|
108
|
+
const IDENTIFIERS = parse(gql`
|
|
109
|
+
query TranscendCliIdentifiers($first: Int!, $offset: Int!) {
|
|
110
|
+
identifiers(
|
|
111
|
+
first: $first
|
|
112
|
+
offset: $offset
|
|
113
|
+
useMaster: false
|
|
114
|
+
orderBy: [{ field: createdAt, direction: ASC }, { field: name, direction: ASC }]
|
|
115
|
+
) {
|
|
116
|
+
nodes {
|
|
117
|
+
id
|
|
118
|
+
name
|
|
119
|
+
type
|
|
120
|
+
regex
|
|
121
|
+
selectOptions
|
|
122
|
+
privacyCenterVisibility
|
|
123
|
+
dataSubjects {
|
|
124
|
+
type
|
|
125
|
+
}
|
|
126
|
+
isRequiredInForm
|
|
127
|
+
placeholder
|
|
128
|
+
displayTitle {
|
|
129
|
+
defaultMessage
|
|
130
|
+
}
|
|
131
|
+
displayDescription {
|
|
132
|
+
defaultMessage
|
|
133
|
+
}
|
|
134
|
+
displayOrder
|
|
135
|
+
isUniqueOnPreferenceStore
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
`);
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/data-inventory/fetchAllIdentifiers.ts
|
|
142
|
+
const PAGE_SIZE$2 = 20;
|
|
143
|
+
/**
|
|
144
|
+
* Fetch all identifiers in the organization
|
|
145
|
+
*
|
|
146
|
+
* @param client - GraphQL client
|
|
147
|
+
* @param options - Options
|
|
148
|
+
* @returns All identifiers in the organization
|
|
149
|
+
*/
|
|
150
|
+
async function fetchAllIdentifiers(client, options) {
|
|
151
|
+
const { logger } = options;
|
|
152
|
+
const identifiers = [];
|
|
153
|
+
let offset = 0;
|
|
154
|
+
let shouldContinue = false;
|
|
155
|
+
do {
|
|
156
|
+
const { identifiers: { nodes } } = await makeGraphQLRequest(client, IDENTIFIERS, {
|
|
157
|
+
logger,
|
|
158
|
+
variables: {
|
|
159
|
+
first: PAGE_SIZE$2,
|
|
160
|
+
offset
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
identifiers.push(...nodes);
|
|
164
|
+
offset += PAGE_SIZE$2;
|
|
165
|
+
shouldContinue = nodes.length === PAGE_SIZE$2;
|
|
166
|
+
} while (shouldContinue);
|
|
167
|
+
return identifiers.sort((a, b) => a.name.localeCompare(b.name));
|
|
168
|
+
}
|
|
169
|
+
//#endregion
|
|
170
|
+
//#region src/preference-management/gqls/purpose.ts
|
|
171
|
+
const PURPOSES = parse(gql`
|
|
172
|
+
query TranscendCliPurposes(
|
|
173
|
+
$first: Int!
|
|
174
|
+
$offset: Int!
|
|
175
|
+
$filterBy: TrackingPurposeFiltersInput
|
|
176
|
+
$input: TrackingPurposeInput!
|
|
177
|
+
) {
|
|
178
|
+
purposes(first: $first, offset: $offset, filterBy: $filterBy, input: $input) {
|
|
179
|
+
nodes {
|
|
180
|
+
id
|
|
181
|
+
name
|
|
182
|
+
description
|
|
183
|
+
defaultConsent
|
|
184
|
+
trackingType
|
|
185
|
+
configurable
|
|
186
|
+
essential
|
|
187
|
+
showInConsentManager
|
|
188
|
+
isActive
|
|
189
|
+
displayOrder
|
|
190
|
+
optOutSignals
|
|
191
|
+
deletedAt
|
|
192
|
+
authLevel
|
|
193
|
+
showInPrivacyCenter
|
|
194
|
+
title
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
`);
|
|
199
|
+
//#endregion
|
|
200
|
+
//#region src/preference-management/fetchAllPurposes.ts
|
|
201
|
+
const PAGE_SIZE$1 = 20;
|
|
202
|
+
/**
|
|
203
|
+
* Fetch all purposes in the organization
|
|
204
|
+
*
|
|
205
|
+
* @param client - GraphQL client
|
|
206
|
+
* @param options - Options
|
|
207
|
+
* @returns All purposes in the organization
|
|
208
|
+
*/
|
|
209
|
+
async function fetchAllPurposes(client, options) {
|
|
210
|
+
const { logger, includeDeleted = false } = options;
|
|
211
|
+
const purposes = [];
|
|
212
|
+
let offset = 0;
|
|
213
|
+
let shouldContinue = false;
|
|
214
|
+
do {
|
|
215
|
+
const { purposes: { nodes } } = await makeGraphQLRequest(client, PURPOSES, {
|
|
216
|
+
logger,
|
|
217
|
+
variables: {
|
|
218
|
+
first: PAGE_SIZE$1,
|
|
219
|
+
offset,
|
|
220
|
+
input: { includeDeleted }
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
purposes.push(...nodes);
|
|
224
|
+
offset += PAGE_SIZE$1;
|
|
225
|
+
shouldContinue = nodes.length === PAGE_SIZE$1;
|
|
226
|
+
} while (shouldContinue);
|
|
227
|
+
return purposes.sort((a, b) => a.trackingType.localeCompare(b.trackingType));
|
|
228
|
+
}
|
|
229
|
+
//#endregion
|
|
230
|
+
//#region src/preference-management/gqls/preferenceTopic.ts
|
|
231
|
+
const PREFERENCE_TOPICS = parse(gql`
|
|
232
|
+
query TranscendCliPreferenceTopics(
|
|
233
|
+
$first: Int!
|
|
234
|
+
$offset: Int!
|
|
235
|
+
$filterBy: PreferenceTopicFilterInput
|
|
236
|
+
) {
|
|
237
|
+
preferenceTopics(first: $first, offset: $offset, filterBy: $filterBy) {
|
|
238
|
+
nodes {
|
|
239
|
+
id
|
|
240
|
+
slug
|
|
241
|
+
type
|
|
242
|
+
title {
|
|
243
|
+
id
|
|
244
|
+
defaultMessage
|
|
245
|
+
}
|
|
246
|
+
showInPrivacyCenter
|
|
247
|
+
displayDescription {
|
|
248
|
+
id
|
|
249
|
+
defaultMessage
|
|
250
|
+
}
|
|
251
|
+
defaultConfiguration
|
|
252
|
+
preferenceOptionValues {
|
|
253
|
+
slug
|
|
254
|
+
title {
|
|
255
|
+
id
|
|
256
|
+
defaultMessage
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
purpose {
|
|
260
|
+
trackingType
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
`);
|
|
266
|
+
//#endregion
|
|
267
|
+
//#region src/preference-management/fetchAllPreferenceTopics.ts
|
|
268
|
+
const PAGE_SIZE = 20;
|
|
269
|
+
/**
|
|
270
|
+
* Fetch all preference topics in the organization
|
|
271
|
+
*
|
|
272
|
+
* @param client - GraphQL client
|
|
273
|
+
* @param options - Options
|
|
274
|
+
* @returns All preference topics in the organization
|
|
275
|
+
*/
|
|
276
|
+
async function fetchAllPreferenceTopics(client, options) {
|
|
277
|
+
const { logger } = options;
|
|
278
|
+
const preferenceTopics = [];
|
|
279
|
+
let offset = 0;
|
|
280
|
+
let shouldContinue = false;
|
|
281
|
+
do {
|
|
282
|
+
const { preferenceTopics: { nodes } } = await makeGraphQLRequest(client, PREFERENCE_TOPICS, {
|
|
283
|
+
logger,
|
|
284
|
+
variables: {
|
|
285
|
+
first: PAGE_SIZE,
|
|
286
|
+
offset
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
preferenceTopics.push(...nodes);
|
|
290
|
+
offset += PAGE_SIZE;
|
|
291
|
+
shouldContinue = nodes.length === PAGE_SIZE;
|
|
292
|
+
} while (shouldContinue);
|
|
293
|
+
return preferenceTopics.sort((a, b) => `${a.slug}:${a.purpose.trackingType}`.localeCompare(`${b.slug}:${b.purpose.trackingType}`));
|
|
294
|
+
}
|
|
295
|
+
//#endregion
|
|
296
|
+
//#region src/preference-management/fetchAllPurposesAndPreferences.ts
|
|
297
|
+
/**
|
|
298
|
+
* Fetch all purposes and preferences
|
|
299
|
+
*
|
|
300
|
+
* @param client - GraphQL client
|
|
301
|
+
* @param options - Options
|
|
302
|
+
* @returns List of purposes with their preference topics
|
|
303
|
+
*/
|
|
304
|
+
async function fetchAllPurposesAndPreferences(client, options) {
|
|
305
|
+
const [purposes, topics] = await Promise.all([fetchAllPurposes(client, options), fetchAllPreferenceTopics(client, options)]);
|
|
306
|
+
return purposes.map((purpose) => ({
|
|
307
|
+
...purpose,
|
|
308
|
+
topics: topics.filter((topic) => topic.purpose.trackingType === purpose.trackingType)
|
|
309
|
+
}));
|
|
310
|
+
}
|
|
311
|
+
//#endregion
|
|
312
|
+
//#region src/preference-management/gqls/preferenceAccessTokens.ts
|
|
313
|
+
const CREATE_PREFERENCE_ACCESS_TOKENS = parse(gql`
|
|
314
|
+
mutation TranscendCliCreatePreferenceAccessTokens($input: CreatePrivacyCenterAccessTokensInput!) {
|
|
315
|
+
createPrivacyCenterAccessTokens(input: $input) {
|
|
316
|
+
nodes {
|
|
317
|
+
token
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
`);
|
|
322
|
+
//#endregion
|
|
323
|
+
//#region src/preference-management/createPreferenceAccessTokens.ts
|
|
324
|
+
const MAX_BATCH_SIZE = 50;
|
|
325
|
+
/**
|
|
326
|
+
* Create preference access tokens for a single page of identifiers.
|
|
327
|
+
*
|
|
328
|
+
* @param client - GraphQL client
|
|
329
|
+
* @param records - Inputs to sign
|
|
330
|
+
* @param logger - Logger
|
|
331
|
+
* @returns list of access tokens
|
|
332
|
+
*/
|
|
333
|
+
async function createPreferenceAccessTokensPage(client, records, logger) {
|
|
334
|
+
const { createPrivacyCenterAccessTokens: { nodes } } = await makeGraphQLRequest(client, CREATE_PREFERENCE_ACCESS_TOKENS, {
|
|
335
|
+
logger,
|
|
336
|
+
variables: { input: { records } }
|
|
337
|
+
});
|
|
338
|
+
return nodes.map((node) => node.token);
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Create preference access tokens for the given identifiers.
|
|
342
|
+
*
|
|
343
|
+
* @see https://docs.transcend.io/docs/articles/preference-management/access-links
|
|
344
|
+
* @param client - GraphQL client
|
|
345
|
+
* @param options - Options
|
|
346
|
+
* @returns list of access tokens/input identifiers
|
|
347
|
+
*/
|
|
348
|
+
async function createPreferenceAccessTokens(client, options) {
|
|
349
|
+
const { records, logger, emitProgress, concurrency = 10 } = options;
|
|
350
|
+
let completed = 0;
|
|
351
|
+
emitProgress?.(0);
|
|
352
|
+
const results = [];
|
|
353
|
+
await map(chunk(records, MAX_BATCH_SIZE), async (chunkedRecords) => {
|
|
354
|
+
const mappedResults = (await createPreferenceAccessTokensPage(client, chunkedRecords.map(({ index, ...rest }) => rest), logger)).map((token, idx) => ({
|
|
355
|
+
input: chunkedRecords[idx],
|
|
356
|
+
accessToken: token
|
|
357
|
+
}));
|
|
358
|
+
results.push(...mappedResults);
|
|
359
|
+
completed += chunkedRecords.length;
|
|
360
|
+
emitProgress?.(completed);
|
|
361
|
+
}, { concurrency });
|
|
362
|
+
return results;
|
|
363
|
+
}
|
|
364
|
+
//#endregion
|
|
365
|
+
//#region src/index.ts
|
|
366
|
+
function createMonorepoPackageDefinition(name, directory) {
|
|
367
|
+
const packageNameParts = describePackageName(name);
|
|
368
|
+
return {
|
|
369
|
+
directory,
|
|
370
|
+
displayName: packageNameParts.displayName,
|
|
371
|
+
packageName: `@transcend-io/${packageNameParts.slug}`
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
//#endregion
|
|
375
|
+
export { buildTranscendGraphQLClient, buildTranscendGraphQLClientGeneric, createMonorepoPackageDefinition, createPreferenceAccessTokens, createSombraGotInstance, fetchAllIdentifiers, fetchAllPreferenceTopics, fetchAllPurposes, fetchAllPurposesAndPreferences, makeGraphQLRequest };
|
|
376
|
+
|
|
377
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["PAGE_SIZE","PAGE_SIZE"],"sources":["../src/api/buildTranscendGraphQLClient.ts","../src/api/makeGraphQLRequest.ts","../src/api/gqls/organization.ts","../src/api/createSombraGotInstance.ts","../src/data-inventory/gqls/identifier.ts","../src/data-inventory/fetchAllIdentifiers.ts","../src/preference-management/gqls/purpose.ts","../src/preference-management/fetchAllPurposes.ts","../src/preference-management/gqls/preferenceTopic.ts","../src/preference-management/fetchAllPreferenceTopics.ts","../src/preference-management/fetchAllPurposesAndPreferences.ts","../src/preference-management/gqls/preferenceAccessTokens.ts","../src/preference-management/createPreferenceAccessTokens.ts","../src/index.ts"],"sourcesContent":["import { GraphQLClient } from 'graphql-request';\n\n/**\n * Create a GraphQL client\n *\n * @param transcendUrl - Transcend API URL\n * @param headers - Request headers to include in each request\n * @param version - Optional version string to include in request headers\n * @returns GraphQL client\n */\nexport function buildTranscendGraphQLClientGeneric(\n transcendUrl: string,\n headers: Record<string, string>,\n version?: string,\n): GraphQLClient {\n return new GraphQLClient(`${transcendUrl}/graphql`, {\n headers: {\n ...headers,\n ...(version ? { version } : {}),\n },\n });\n}\n\n/**\n * Create a GraphQL client capable of submitting requests with an API key\n *\n * @param transcendUrl - Transcend API URL\n * @param auth - API key to authenticate to API\n * @param version - Optional version string to include in request headers\n * @returns GraphQL client\n */\nexport function buildTranscendGraphQLClient(\n transcendUrl: string,\n auth: string,\n version?: string,\n): GraphQLClient {\n return buildTranscendGraphQLClientGeneric(\n transcendUrl,\n { Authorization: `Bearer ${auth}` },\n version,\n );\n}\n","import { sleepPromise, type Logger } from '@transcend-io/utils';\nimport type { GraphQLClient, RequestDocument, Variables } from 'graphql-request';\n\nconst DEFAULT_MAX_RETRIES = 4;\n\nconst KNOWN_ERRORS = [\n 'syntax error',\n 'got invalid value',\n 'Client error',\n 'cannot affect row a second time',\n 'GRAPHQL_VALIDATION_FAILED',\n];\n\n/**\n * Make a GraphQL request with retries\n *\n * @param client - GraphQL client\n * @param document - GraphQL document\n * @param options - Options including logger, variables, headers, and retry config\n * @returns Response\n */\nexport async function makeGraphQLRequest<T, V extends Variables = Variables>(\n client: GraphQLClient,\n document: RequestDocument,\n options: {\n /** GraphQL variables */\n variables?: V;\n /** Logger for retry/error messages */\n logger: Logger;\n /** Additional request headers */\n requestHeaders?: Record<string, string> | string[][] | Headers;\n /** Max number of retry attempts (default 4) */\n maxRetries?: number;\n },\n): Promise<T> {\n const { variables, logger, requestHeaders, maxRetries = DEFAULT_MAX_RETRIES } = options;\n\n let retryCount = 0;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n try {\n const result = await client.request(document, variables, requestHeaders);\n return result as T;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (err: any) {\n if (err.message?.includes('API key is invalid')) {\n throw new Error(\n 'API key is invalid. ' +\n 'Please ensure that the key provided has the proper scope and is not expired, ' +\n 'and that the transcendUrl corresponds to the correct backend for your organization.',\n );\n }\n\n if (KNOWN_ERRORS.some((msg) => err.message?.includes(msg))) {\n throw err;\n }\n\n if (err.message?.startsWith('Client error: Too many requests')) {\n const rateLimitResetAt = err.response?.headers?.get('x-ratelimit-reset');\n const sleepTime = rateLimitResetAt\n ? new Date(rateLimitResetAt).getTime() - new Date().getTime() + 100\n : 1000 * 10;\n logger.warn(`DETECTED RATE LIMIT: ${err.message}. Sleeping for ${sleepTime}ms`);\n await sleepPromise(sleepTime);\n }\n\n if (retryCount >= maxRetries) {\n throw err;\n }\n retryCount += 1;\n logger.warn(`Retrying failed request (${retryCount} / ${maxRetries}): ${err.message}`);\n }\n }\n}\n","import { parse, type DocumentNode } from 'graphql';\nimport { gql } from 'graphql-request';\n\nexport const ORGANIZATION: DocumentNode = parse(gql`\n query TranscendCliOrganization {\n organization {\n sombra {\n customerUrl\n }\n }\n }\n`);\n","import type { Logger } from '@transcend-io/utils';\nimport got, { type Got } from 'got';\n\nimport { buildTranscendGraphQLClient } from './buildTranscendGraphQLClient.js';\nimport { ORGANIZATION } from './gqls/organization.js';\nimport { makeGraphQLRequest } from './makeGraphQLRequest.js';\n\n/**\n * Instantiate an instance of got that is capable of making requests\n * to a sombra gateway.\n *\n * @param transcendUrl - URL of Transcend API\n * @param transcendApiKey - Transcend API key\n * @param options - Additional options\n * @returns The instance of got that is capable of making requests to the customer ingress\n */\nexport async function createSombraGotInstance(\n transcendUrl: string,\n transcendApiKey: string,\n options: {\n /** Logger instance */\n logger: Logger;\n /** Sombra API key */\n sombraApiKey?: string;\n /** Override Sombra URL (replaces process.env.SOMBRA_URL lookup) */\n sombraUrl?: string;\n },\n): Promise<Got> {\n const { logger, sombraApiKey, sombraUrl } = options;\n\n const client = buildTranscendGraphQLClient(transcendUrl, transcendApiKey);\n const { organization } = await makeGraphQLRequest<{\n /** Organization */\n organization: {\n /** Primary Sombra */\n sombra: {\n /** URL */\n customerUrl: string;\n };\n };\n }>(client, ORGANIZATION, { logger });\n\n const { customerUrl } = organization.sombra;\n const sombraToUse = sombraUrl || customerUrl;\n\n if (\n !sombraUrl &&\n [\n 'https://sombra-reverse-tunnel.transcend.io',\n 'https://sombra-reverse-tunnel.us.transcend.io',\n ].includes(customerUrl)\n ) {\n throw new Error(\n 'It looks like your Sombra customer ingress URL has not been set up. ' +\n 'Please follow the instructions here to configure networking for Sombra: ' +\n 'https://docs.transcend.io/docs/articles/sombra/deploying/customizing-sombra/networking',\n );\n }\n logger.info(`Using sombra: ${sombraToUse}`);\n\n return got.extend({\n prefixUrl: sombraToUse,\n headers: {\n Authorization: `Bearer ${transcendApiKey}`,\n ...(sombraApiKey ? { 'X-Sombra-Authorization': `Bearer ${sombraApiKey}` } : {}),\n },\n });\n}\n","import { parse, type DocumentNode } from 'graphql';\nimport { gql } from 'graphql-request';\n\nexport const IDENTIFIERS: DocumentNode = parse(gql`\n query TranscendCliIdentifiers($first: Int!, $offset: Int!) {\n identifiers(\n first: $first\n offset: $offset\n useMaster: false\n orderBy: [{ field: createdAt, direction: ASC }, { field: name, direction: ASC }]\n ) {\n nodes {\n id\n name\n type\n regex\n selectOptions\n privacyCenterVisibility\n dataSubjects {\n type\n }\n isRequiredInForm\n placeholder\n displayTitle {\n defaultMessage\n }\n displayDescription {\n defaultMessage\n }\n displayOrder\n isUniqueOnPreferenceStore\n }\n }\n }\n`);\n","import { IdentifierType, RequestAction } from '@transcend-io/privacy-types';\nimport type { Logger } from '@transcend-io/utils';\nimport type { GraphQLClient } from 'graphql-request';\n\nimport { makeGraphQLRequest } from '../api/makeGraphQLRequest.js';\nimport { IDENTIFIERS } from './gqls/identifier.js';\n\nexport interface Identifier {\n /** ID of identifier */\n id: string;\n /** Name of identifier */\n name: string;\n /** The type of identifier */\n type: IdentifierType;\n /** Regular expression */\n regex: string;\n /** The set of options that the identifier supports */\n selectOptions: string[];\n /** Whether identifier is enabled on privacy center */\n privacyCenterVisibility: RequestAction[];\n /** Enabled data subjects that are exposed this identifier on the privacy center */\n dataSubjects: { /** type of data subjects */ type: string }[];\n /** Whether identifier is a required field in privacy center form */\n isRequiredInForm: boolean;\n /** Identifier placeholder text */\n placeholder: string;\n /** Display title for identifier */\n displayTitle: { /** Default message */ defaultMessage: string };\n /** Display description for identifier */\n displayDescription: { /** Default */ defaultMessage: string };\n /** Display order */\n displayOrder: number;\n /** Does this identifier uniquely identify a consent record */\n isUniqueOnPreferenceStore: boolean;\n}\n\nconst PAGE_SIZE = 20;\n\n/**\n * Fetch all identifiers in the organization\n *\n * @param client - GraphQL client\n * @param options - Options\n * @returns All identifiers in the organization\n */\nexport async function fetchAllIdentifiers(\n client: GraphQLClient,\n options: { /** Logger instance */ logger: Logger },\n): Promise<Identifier[]> {\n const { logger } = options;\n const identifiers: Identifier[] = [];\n let offset = 0;\n\n let shouldContinue = false;\n do {\n const {\n identifiers: { nodes },\n } = await makeGraphQLRequest<{\n /** Identifiers */\n identifiers: { /** List */ nodes: Identifier[] };\n }>(client, IDENTIFIERS, {\n logger,\n variables: { first: PAGE_SIZE, offset },\n });\n identifiers.push(...nodes);\n offset += PAGE_SIZE;\n shouldContinue = nodes.length === PAGE_SIZE;\n } while (shouldContinue);\n\n return identifiers.sort((a, b) => a.name.localeCompare(b.name));\n}\n","import { parse, type DocumentNode } from 'graphql';\nimport { gql } from 'graphql-request';\n\nexport const PURPOSES: DocumentNode = parse(gql`\n query TranscendCliPurposes(\n $first: Int!\n $offset: Int!\n $filterBy: TrackingPurposeFiltersInput\n $input: TrackingPurposeInput!\n ) {\n purposes(first: $first, offset: $offset, filterBy: $filterBy, input: $input) {\n nodes {\n id\n name\n description\n defaultConsent\n trackingType\n configurable\n essential\n showInConsentManager\n isActive\n displayOrder\n optOutSignals\n deletedAt\n authLevel\n showInPrivacyCenter\n title\n }\n }\n }\n`);\n","import { UserPrivacySignalEnum } from '@transcend-io/airgap.js-types';\nimport { DefaultConsentOption, PreferenceStoreAuthLevel } from '@transcend-io/privacy-types';\nimport type { Logger } from '@transcend-io/utils';\nimport type { GraphQLClient } from 'graphql-request';\n\nimport { makeGraphQLRequest } from '../api/makeGraphQLRequest.js';\nimport { PURPOSES } from './gqls/purpose.js';\n\nexport interface Purpose {\n /** ID of purpose */\n id: string;\n /** Name of purpose */\n name: string;\n /** Description of purpose */\n description: string;\n /** Default consent status */\n defaultConsent: DefaultConsentOption;\n /** Slug of purpose */\n trackingType: string;\n /** Whether the purpose is configurable */\n configurable: boolean;\n /** Whether the purpose is essential */\n essential: boolean;\n /** Whether to show the purpose in the consent manager */\n showInConsentManager: boolean;\n /** Whether the purpose is active */\n isActive: boolean;\n /** Display order of the purpose */\n displayOrder: number;\n /** Opt-out signals for the purpose */\n optOutSignals: UserPrivacySignalEnum[];\n /** Whether the purpose is deleted */\n deletedAt?: string;\n /** Authorization level required for the purpose */\n authLevel: PreferenceStoreAuthLevel;\n /** Whether to show the purpose in the privacy center */\n showInPrivacyCenter: boolean;\n /** Title of the purpose */\n title: string;\n}\n\nconst PAGE_SIZE = 20;\n\n/**\n * Fetch all purposes in the organization\n *\n * @param client - GraphQL client\n * @param options - Options\n * @returns All purposes in the organization\n */\nexport async function fetchAllPurposes(\n client: GraphQLClient,\n options: {\n /** Logger instance */\n logger: Logger;\n /** Whether to include deleted purposes */\n includeDeleted?: boolean;\n },\n): Promise<Purpose[]> {\n const { logger, includeDeleted = false } = options;\n const purposes: Purpose[] = [];\n let offset = 0;\n\n let shouldContinue = false;\n do {\n const {\n purposes: { nodes },\n } = await makeGraphQLRequest<{\n /** Purposes */\n purposes: { /** List */ nodes: Purpose[] };\n }>(client, PURPOSES, {\n logger,\n variables: { first: PAGE_SIZE, offset, input: { includeDeleted } },\n });\n purposes.push(...nodes);\n offset += PAGE_SIZE;\n shouldContinue = nodes.length === PAGE_SIZE;\n } while (shouldContinue);\n\n return purposes.sort((a, b) => a.trackingType.localeCompare(b.trackingType));\n}\n","import { parse, type DocumentNode } from 'graphql';\nimport { gql } from 'graphql-request';\n\nexport const PREFERENCE_TOPICS: DocumentNode = parse(gql`\n query TranscendCliPreferenceTopics(\n $first: Int!\n $offset: Int!\n $filterBy: PreferenceTopicFilterInput\n ) {\n preferenceTopics(first: $first, offset: $offset, filterBy: $filterBy) {\n nodes {\n id\n slug\n type\n title {\n id\n defaultMessage\n }\n showInPrivacyCenter\n displayDescription {\n id\n defaultMessage\n }\n defaultConfiguration\n preferenceOptionValues {\n slug\n title {\n id\n defaultMessage\n }\n }\n purpose {\n trackingType\n }\n }\n }\n }\n`);\n","import { PreferenceTopicType } from '@transcend-io/privacy-types';\nimport type { Logger } from '@transcend-io/utils';\nimport type { GraphQLClient } from 'graphql-request';\n\nimport { makeGraphQLRequest } from '../api/makeGraphQLRequest.js';\nimport { PREFERENCE_TOPICS } from './gqls/preferenceTopic.js';\n\nexport interface PreferenceTopic {\n /** ID of preference topic */\n id: string;\n /** Slug of preference topic */\n slug: string;\n /** Title of topic */\n title: { /** ID */ id: string; /** Default message */ defaultMessage: string };\n /** Whether to show in privacy center */\n showInPrivacyCenter: boolean;\n /** Description to display in privacy center */\n displayDescription: { /** ID */ id: string; /** Default message */ defaultMessage: string };\n /** Type of preference topic */\n type: PreferenceTopicType;\n /** Default configuration */\n defaultConfiguration: string;\n /** Option values */\n preferenceOptionValues: {\n /** Slug of value */\n slug: string;\n /** Title of value */\n title: { /** ID */ id: string; /** Default message */ defaultMessage: string };\n }[];\n /** Related purpose */\n purpose: { /** Slug */ trackingType: string };\n}\n\nconst PAGE_SIZE = 20;\n\n/**\n * Fetch all preference topics in the organization\n *\n * @param client - GraphQL client\n * @param options - Options\n * @returns All preference topics in the organization\n */\nexport async function fetchAllPreferenceTopics(\n client: GraphQLClient,\n options: {\n /** Logger instance */\n logger: Logger;\n },\n): Promise<PreferenceTopic[]> {\n const { logger } = options;\n const preferenceTopics: PreferenceTopic[] = [];\n let offset = 0;\n\n let shouldContinue = false;\n do {\n const {\n preferenceTopics: { nodes },\n } = await makeGraphQLRequest<{\n /** Preference topics */\n preferenceTopics: { /** List */ nodes: PreferenceTopic[] };\n }>(client, PREFERENCE_TOPICS, {\n logger,\n variables: { first: PAGE_SIZE, offset },\n });\n preferenceTopics.push(...nodes);\n offset += PAGE_SIZE;\n shouldContinue = nodes.length === PAGE_SIZE;\n } while (shouldContinue);\n\n return preferenceTopics.sort((a, b) =>\n `${a.slug}:${a.purpose.trackingType}`.localeCompare(`${b.slug}:${b.purpose.trackingType}`),\n );\n}\n","import type { Logger } from '@transcend-io/utils';\nimport type { GraphQLClient } from 'graphql-request';\n\nimport { type PreferenceTopic, fetchAllPreferenceTopics } from './fetchAllPreferenceTopics.js';\nimport { type Purpose, fetchAllPurposes } from './fetchAllPurposes.js';\n\nexport interface PurposeWithPreferences extends Purpose {\n /** Topics */\n topics: PreferenceTopic[];\n}\n\n/**\n * Fetch all purposes and preferences\n *\n * @param client - GraphQL client\n * @param options - Options\n * @returns List of purposes with their preference topics\n */\nexport async function fetchAllPurposesAndPreferences(\n client: GraphQLClient,\n options: { /** Logger instance */ logger: Logger },\n): Promise<PurposeWithPreferences[]> {\n const [purposes, topics] = await Promise.all([\n fetchAllPurposes(client, options),\n fetchAllPreferenceTopics(client, options),\n ]);\n\n return purposes.map((purpose) => ({\n ...purpose,\n topics: topics.filter((topic) => topic.purpose.trackingType === purpose.trackingType),\n }));\n}\n","import { parse, type DocumentNode } from 'graphql';\nimport { gql } from 'graphql-request';\n\nexport const CREATE_PREFERENCE_ACCESS_TOKENS: DocumentNode = parse(gql`\n mutation TranscendCliCreatePreferenceAccessTokens($input: CreatePrivacyCenterAccessTokensInput!) {\n createPrivacyCenterAccessTokens(input: $input) {\n nodes {\n token\n }\n }\n }\n`);\n","import type { SombraStandardScope } from '@transcend-io/privacy-types';\nimport { map, type Logger } from '@transcend-io/utils';\nimport type { GraphQLClient } from 'graphql-request';\nimport { chunk } from 'lodash-es';\n\nimport { makeGraphQLRequest } from '../api/makeGraphQLRequest.js';\nimport { CREATE_PREFERENCE_ACCESS_TOKENS } from './gqls/preferenceAccessTokens.js';\n\nexport interface PreferenceAccessTokenInput {\n /** Slug of data subject to authenticate as */\n subjectType: string;\n /** Scopes to grant */\n scopes: SombraStandardScope[];\n /** Expiration time in seconds */\n expiresIn?: number;\n /** Email address of user */\n email: string;\n /** Core identifier for the user */\n coreIdentifier?: string;\n}\n\nexport interface PreferenceAccessTokenInputWithIndex extends PreferenceAccessTokenInput {\n /** Index of the input record */\n index?: number;\n}\n\nconst MAX_BATCH_SIZE = 50;\n\n/**\n * Create preference access tokens for a single page of identifiers.\n *\n * @param client - GraphQL client\n * @param records - Inputs to sign\n * @param logger - Logger\n * @returns list of access tokens\n */\nasync function createPreferenceAccessTokensPage(\n client: GraphQLClient,\n records: PreferenceAccessTokenInput[],\n logger: Logger,\n): Promise<string[]> {\n const {\n createPrivacyCenterAccessTokens: { nodes },\n } = await makeGraphQLRequest<{\n /** createPrivacyCenterAccessTokens mutation */\n createPrivacyCenterAccessTokens: {\n /** Nodes */\n nodes: { /** Token */ token: string }[];\n };\n }>(client, CREATE_PREFERENCE_ACCESS_TOKENS, {\n logger,\n variables: { input: { records } },\n });\n return nodes.map((node) => node.token);\n}\n\n/**\n * Create preference access tokens for the given identifiers.\n *\n * @see https://docs.transcend.io/docs/articles/preference-management/access-links\n * @param client - GraphQL client\n * @param options - Options\n * @returns list of access tokens/input identifiers\n */\nexport async function createPreferenceAccessTokens(\n client: GraphQLClient,\n options: {\n /** Records to create tokens for */\n records: PreferenceAccessTokenInputWithIndex[];\n /** Logger instance */\n logger: Logger;\n /** Optional progress emitter */\n emitProgress?: (progress: number) => void;\n /** Number of concurrent requests to make (default: 10) */\n concurrency?: number;\n },\n): Promise<\n {\n /** Identifier for the record */\n input: PreferenceAccessTokenInputWithIndex;\n /** Access token */\n accessToken: string;\n }[]\n> {\n const { records, logger, emitProgress, concurrency = 10 } = options;\n\n let completed = 0;\n emitProgress?.(0);\n\n const results: {\n /** Identifier for the record */\n input: PreferenceAccessTokenInput;\n /** Access token */\n accessToken: string;\n }[] = [];\n\n await map(\n chunk(records, MAX_BATCH_SIZE),\n async (chunkedRecords) => {\n const tokens = await createPreferenceAccessTokensPage(\n client,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n chunkedRecords.map(({ index, ...rest }) => rest),\n logger,\n );\n const mappedResults = tokens.map((token, idx) => ({\n input: chunkedRecords[idx]!,\n accessToken: token,\n }));\n results.push(...mappedResults);\n completed += chunkedRecords.length;\n emitProgress?.(completed);\n },\n { concurrency },\n );\n\n return results;\n}\n","import { describePackageName } from '@transcend-io/utils';\n\nexport interface MonorepoPackageDefinition {\n directory: string;\n displayName: string;\n packageName: string;\n}\n\nexport function createMonorepoPackageDefinition(\n name: string,\n directory: string,\n): MonorepoPackageDefinition {\n const packageNameParts = describePackageName(name);\n\n return {\n directory,\n displayName: packageNameParts.displayName,\n packageName: `@transcend-io/${packageNameParts.slug}`,\n };\n}\n\nexport * from './api/index.js';\nexport * from './data-inventory/index.js';\nexport * from './preference-management/index.js';\n"],"mappings":";;;;;;;;;;;;;;AAUA,SAAgB,mCACd,cACA,SACA,SACe;AACf,QAAO,IAAI,cAAc,GAAG,aAAa,WAAW,EAClD,SAAS;EACP,GAAG;EACH,GAAI,UAAU,EAAE,SAAS,GAAG,EAAE;EAC/B,EACF,CAAC;;;;;;;;;;AAWJ,SAAgB,4BACd,cACA,MACA,SACe;AACf,QAAO,mCACL,cACA,EAAE,eAAe,UAAU,QAAQ,EACnC,QACD;;;;ACrCH,MAAM,sBAAsB;AAE5B,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACD;;;;;;;;;AAUD,eAAsB,mBACpB,QACA,UACA,SAUY;CACZ,MAAM,EAAE,WAAW,QAAQ,gBAAgB,aAAa,wBAAwB;CAEhF,IAAI,aAAa;AAEjB,QAAO,KACL,KAAI;AAEF,SADe,MAAM,OAAO,QAAQ,UAAU,WAAW,eAAe;UAGjE,KAAU;AACjB,MAAI,IAAI,SAAS,SAAS,qBAAqB,CAC7C,OAAM,IAAI,MACR,uLAGD;AAGH,MAAI,aAAa,MAAM,QAAQ,IAAI,SAAS,SAAS,IAAI,CAAC,CACxD,OAAM;AAGR,MAAI,IAAI,SAAS,WAAW,kCAAkC,EAAE;GAC9D,MAAM,mBAAmB,IAAI,UAAU,SAAS,IAAI,oBAAoB;GACxE,MAAM,YAAY,mBACd,IAAI,KAAK,iBAAiB,CAAC,SAAS,oBAAG,IAAI,MAAM,EAAC,SAAS,GAAG,MAC9D,MAAO;AACX,UAAO,KAAK,wBAAwB,IAAI,QAAQ,iBAAiB,UAAU,IAAI;AAC/E,SAAM,aAAa,UAAU;;AAG/B,MAAI,cAAc,WAChB,OAAM;AAER,gBAAc;AACd,SAAO,KAAK,4BAA4B,WAAW,KAAK,WAAW,KAAK,IAAI,UAAU;;;;;ACnE5F,MAAa,eAA6B,MAAM,GAAG;;;;;;;;EAQjD;;;;;;;;;;;;ACKF,eAAsB,wBACpB,cACA,iBACA,SAQc;CACd,MAAM,EAAE,QAAQ,cAAc,cAAc;CAG5C,MAAM,EAAE,iBAAiB,MAAM,mBADhB,4BAA4B,cAAc,gBAAgB,EAU9D,cAAc,EAAE,QAAQ,CAAC;CAEpC,MAAM,EAAE,gBAAgB,aAAa;CACrC,MAAM,cAAc,aAAa;AAEjC,KACE,CAAC,aACD,CACE,8CACA,gDACD,CAAC,SAAS,YAAY,CAEvB,OAAM,IAAI,MACR,qOAGD;AAEH,QAAO,KAAK,iBAAiB,cAAc;AAE3C,QAAO,IAAI,OAAO;EAChB,WAAW;EACX,SAAS;GACP,eAAe,UAAU;GACzB,GAAI,eAAe,EAAE,0BAA0B,UAAU,gBAAgB,GAAG,EAAE;GAC/E;EACF,CAAC;;;;AC/DJ,MAAa,cAA4B,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BhD;;;ACEF,MAAMA,cAAY;;;;;;;;AASlB,eAAsB,oBACpB,QACA,SACuB;CACvB,MAAM,EAAE,WAAW;CACnB,MAAM,cAA4B,EAAE;CACpC,IAAI,SAAS;CAEb,IAAI,iBAAiB;AACrB,IAAG;EACD,MAAM,EACJ,aAAa,EAAE,YACb,MAAM,mBAGP,QAAQ,aAAa;GACtB;GACA,WAAW;IAAE,OAAOA;IAAW;IAAQ;GACxC,CAAC;AACF,cAAY,KAAK,GAAG,MAAM;AAC1B,YAAUA;AACV,mBAAiB,MAAM,WAAWA;UAC3B;AAET,QAAO,YAAY,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,KAAK,CAAC;;;;AClEjE,MAAa,WAAyB,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2B7C;;;ACWF,MAAMC,cAAY;;;;;;;;AASlB,eAAsB,iBACpB,QACA,SAMoB;CACpB,MAAM,EAAE,QAAQ,iBAAiB,UAAU;CAC3C,MAAM,WAAsB,EAAE;CAC9B,IAAI,SAAS;CAEb,IAAI,iBAAiB;AACrB,IAAG;EACD,MAAM,EACJ,UAAU,EAAE,YACV,MAAM,mBAGP,QAAQ,UAAU;GACnB;GACA,WAAW;IAAE,OAAOA;IAAW;IAAQ,OAAO,EAAE,gBAAgB;IAAE;GACnE,CAAC;AACF,WAAS,KAAK,GAAG,MAAM;AACvB,YAAUA;AACV,mBAAiB,MAAM,WAAWA;UAC3B;AAET,QAAO,SAAS,MAAM,GAAG,MAAM,EAAE,aAAa,cAAc,EAAE,aAAa,CAAC;;;;AC5E9E,MAAa,oBAAkC,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCtD;;;ACJF,MAAM,YAAY;;;;;;;;AASlB,eAAsB,yBACpB,QACA,SAI4B;CAC5B,MAAM,EAAE,WAAW;CACnB,MAAM,mBAAsC,EAAE;CAC9C,IAAI,SAAS;CAEb,IAAI,iBAAiB;AACrB,IAAG;EACD,MAAM,EACJ,kBAAkB,EAAE,YAClB,MAAM,mBAGP,QAAQ,mBAAmB;GAC5B;GACA,WAAW;IAAE,OAAO;IAAW;IAAQ;GACxC,CAAC;AACF,mBAAiB,KAAK,GAAG,MAAM;AAC/B,YAAU;AACV,mBAAiB,MAAM,WAAW;UAC3B;AAET,QAAO,iBAAiB,MAAM,GAAG,MAC/B,GAAG,EAAE,KAAK,GAAG,EAAE,QAAQ,eAAe,cAAc,GAAG,EAAE,KAAK,GAAG,EAAE,QAAQ,eAAe,CAC3F;;;;;;;;;;;ACrDH,eAAsB,+BACpB,QACA,SACmC;CACnC,MAAM,CAAC,UAAU,UAAU,MAAM,QAAQ,IAAI,CAC3C,iBAAiB,QAAQ,QAAQ,EACjC,yBAAyB,QAAQ,QAAQ,CAC1C,CAAC;AAEF,QAAO,SAAS,KAAK,aAAa;EAChC,GAAG;EACH,QAAQ,OAAO,QAAQ,UAAU,MAAM,QAAQ,iBAAiB,QAAQ,aAAa;EACtF,EAAE;;;;AC3BL,MAAa,kCAAgD,MAAM,GAAG;;;;;;;;EAQpE;;;ACeF,MAAM,iBAAiB;;;;;;;;;AAUvB,eAAe,iCACb,QACA,SACA,QACmB;CACnB,MAAM,EACJ,iCAAiC,EAAE,YACjC,MAAM,mBAMP,QAAQ,iCAAiC;EAC1C;EACA,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE;EAClC,CAAC;AACF,QAAO,MAAM,KAAK,SAAS,KAAK,MAAM;;;;;;;;;;AAWxC,eAAsB,6BACpB,QACA,SAiBA;CACA,MAAM,EAAE,SAAS,QAAQ,cAAc,cAAc,OAAO;CAE5D,IAAI,YAAY;AAChB,gBAAe,EAAE;CAEjB,MAAM,UAKA,EAAE;AAER,OAAM,IACJ,MAAM,SAAS,eAAe,EAC9B,OAAO,mBAAmB;EAOxB,MAAM,iBANS,MAAM,iCACnB,QAEA,eAAe,KAAK,EAAE,OAAO,GAAG,WAAW,KAAK,EAChD,OACD,EAC4B,KAAK,OAAO,SAAS;GAChD,OAAO,eAAe;GACtB,aAAa;GACd,EAAE;AACH,UAAQ,KAAK,GAAG,cAAc;AAC9B,eAAa,eAAe;AAC5B,iBAAe,UAAU;IAE3B,EAAE,aAAa,CAChB;AAED,QAAO;;;;AC5GT,SAAgB,gCACd,MACA,WAC2B;CAC3B,MAAM,mBAAmB,oBAAoB,KAAK;AAElD,QAAO;EACL;EACA,aAAa,iBAAiB;EAC9B,aAAa,iBAAiB,iBAAiB;EAChD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@transcend-io/sdk",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Transcend SDK — shared GraphQL/REST API clients and preference management utilities.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"type": "module",
|
|
10
|
+
"sideEffects": false,
|
|
11
|
+
"types": "./dist/index.d.mts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"@transcend-io/source": "./src/index.ts",
|
|
15
|
+
"types": "./dist/index.d.mts",
|
|
16
|
+
"default": "./dist/index.mjs"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsdown",
|
|
24
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"check-exports": "attw --pack . --ignore-rules cjs-resolves-to-esm"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@transcend-io/airgap.js-types": "^12.16.0",
|
|
30
|
+
"@transcend-io/privacy-types": "workspace:*",
|
|
31
|
+
"@transcend-io/utils": "workspace:*",
|
|
32
|
+
"got": "^11.8.5",
|
|
33
|
+
"graphql": "^16.6.0",
|
|
34
|
+
"graphql-request": "^5.0.0",
|
|
35
|
+
"lodash-es": "^4.17.21"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@arethetypeswrong/cli": "catalog:",
|
|
39
|
+
"@types/lodash-es": "^4.17.12",
|
|
40
|
+
"@types/node": "catalog:",
|
|
41
|
+
"tsdown": "catalog:",
|
|
42
|
+
"typescript": "catalog:",
|
|
43
|
+
"vitest": "catalog:"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=22.0.0"
|
|
47
|
+
}
|
|
48
|
+
}
|