Skip to content

Commit b884606

Browse files
authored
Chore/fix copy command (#23)
1 parent 0313548 commit b884606

File tree

5 files changed

+63
-19
lines changed

5 files changed

+63
-19
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
build/
2+
dist/

README.md

+6-8
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,12 @@ process. Head over the to the [detailed docs
9595
here](docs/GOOGLE-API-CREDENTIALS-SETUP.md) to setup the Service Account and
9696
generate your credentials.
9797

98-
Now that you have your credentials in a JSON file (let's say
99-
`credentials.json`), you are ready to tell `gtm-tools` how to use these
100-
credentials by setting the environment variable `GOOGLE_APPLICATION_CREDENTIALS`.
98+
Now that you have your credentials in a JSON file, which is also known as the
99+
key file (let's call this file `credentials.json`), you are ready to tell
100+
`gtm-tools` how to use these credentials. Do so by updating the path to
101+
`tagManagerAPI.googleAuthKeyFile` config in `config.json` file.
101102

102-
```
103-
export GOOGLE_APPLICATION_CREDENTIALS=<path-to-credentials>/credentials.json
104-
```
105-
106-
Now test these credentials with `gtm-tools` by running the following command:
103+
Now, test these credentials with `gtm-tools` by running the following command:
107104

108105
```
109106
gtm-tools --config config.json list -aa gtm-prod
@@ -116,6 +113,7 @@ account.
116113

117114
| Configuration Key | Type | Default | Required | Description |
118115
|--------------------------------------------|---------------------|---------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
116+
| `tagManagerAPI.googleAuthKeyFile` | string | | Yes | Path to the Google Auth API credentials or key file download from Google Cloud Console. Read the [detailed docs here](docs/GOOGLE-API-CREDENTIALS-SETUP.md) to understand how to get your key file. |
119117
| `tagManagerAPI.defaultRateLimitBatchSize` | int | 1 | | Batch size for the count of API requests to be made to Tag Manager API without a delay. After this batch, a delay will be injected before the next batch starts, controlled by `defaultRateLimitBatchDelay`. |
120118
| `tagManagerAPI.defaultRateLimitBatchDelay` | int | 5000 | | Add delay (in milliseconds) between subsequent batches of requests to Tag Manager API to avoid rate limiting. |
121119
| `accounts[].alias` | string | | Yes | Human-friendly alias to refer to the account while using `gtm-tools`. |

src/config.ts

+48-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ import {
99
IsNumber,
1010
IsPositive,
1111
MinLength,
12+
Validate,
13+
ValidationError,
14+
ValidatorConstraint,
15+
ValidatorConstraintInterface,
1216
} from 'class-validator';
1317

18+
import fs from 'fs';
19+
1420
abstract class AbstractConfig {
1521
fixTypes() {}
1622
}
@@ -60,7 +66,22 @@ class AccountConfig extends AbstractConfig {
6066
}
6167
}
6268

69+
@ValidatorConstraint({name: 'customText', async: false})
70+
export class IsValidGoogleAuthKeyFile implements ValidatorConstraintInterface {
71+
validate(text: string) {
72+
// test if text ends with .json and the file exists
73+
return text !== undefined && text.endsWith('.json') && fs.existsSync(text);
74+
}
75+
76+
defaultMessage() {
77+
return 'Value for $property ($value) should be a valid file path ".json" extension and must exist at that path.';
78+
}
79+
}
80+
6381
class TagManagerAPIConfig extends AbstractConfig {
82+
@Validate(IsValidGoogleAuthKeyFile) // 6 characters for at least ".json" and a name of the file
83+
googleAuthKeyFile: string;
84+
6485
@IsNumber()
6586
@IsPositive()
6687
defaultRateLimitBatchSize: number;
@@ -70,10 +91,12 @@ class TagManagerAPIConfig extends AbstractConfig {
7091
defaultRateLimitBatchDelay: number;
7192

7293
constructor(
73-
defaultRateLimitBatchSize = 5, // 15 requests per minute
74-
defaultRateLimitBatchDelay = 15000 // 15 seconds
94+
googleAuthKeyFile: string,
95+
defaultRateLimitBatchSize = 1, // 1 request per batch
96+
defaultRateLimitBatchDelay = 5000 // 5 seconds
7597
) {
7698
super();
99+
this.googleAuthKeyFile = googleAuthKeyFile;
77100
this.defaultRateLimitBatchSize = defaultRateLimitBatchSize;
78101
this.defaultRateLimitBatchDelay = defaultRateLimitBatchDelay;
79102
}
@@ -93,7 +116,7 @@ export class Config extends AbstractConfig {
93116
constructor(tagManagerAPI?: TagManagerAPIConfig, accounts?: AccountConfig[]) {
94117
super();
95118
if (tagManagerAPI === undefined) {
96-
this.tagManagerAPI = new TagManagerAPIConfig();
119+
this.tagManagerAPI = new TagManagerAPIConfig('');
97120
} else {
98121
this.tagManagerAPI = tagManagerAPI;
99122
}
@@ -123,4 +146,26 @@ export class Config extends AbstractConfig {
123146
}
124147
return matchedAccounts ? matchedAccounts[0] : undefined;
125148
}
149+
150+
formatError(error: ValidationError): string {
151+
// TODO: this function can be implemented in a better way. This is just a quick hack.
152+
const delimiter = '\n - ';
153+
let msg = '';
154+
msg += error.property + ': ' + '\n';
155+
156+
if (error.constraints) {
157+
msg += (' - ' + Object.values(error.constraints).join(delimiter))
158+
.split('\n')
159+
.join('\n ');
160+
}
161+
162+
if (error.children && error?.children.length > 0) {
163+
msg += '';
164+
error.children?.forEach(child => {
165+
msg += ' ' + this.formatError(child).split('\n').join('\n ') + '\n';
166+
});
167+
}
168+
169+
return msg;
170+
}
126171
}

src/core.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export class TagManagerData {
7777

7878
async init() {
7979
const auth = new google.auth.GoogleAuth({
80-
// Scopes can be specified either as an array or as a single, space-delimited string.
80+
keyFile: this.config.tagManagerAPI.googleAuthKeyFile,
8181
scopes: [
8282
'https://www.googleapis.com/auth/tagmanager.edit.containers',
8383
'https://www.googleapis.com/auth/tagmanager.manage.accounts',

src/index.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,18 @@ cli.hook('preAction', async () => {
3333

3434
await validate(configObj, {forbidUnknownValues: false}).then(errors => {
3535
if (errors.length > 0) {
36-
cli.error('Invalid configuration file. Validation failed.'.red);
36+
cli.error(
37+
(
38+
'Invalid configuration file. Validation failed.' +
39+
'\n\n' +
40+
configObj.formatError(errors[0])
41+
).red
42+
);
3743
}
3844
});
3945
});
4046

4147
async function main() {
42-
if (!process.env.GOOGLE_APPLICATION_CREDENTIALS) {
43-
cli.error(
44-
'GOOGLE_APPLICATION_CREDENTIALS environment variable must be set and pointing to a valid Google API credentials.json file.'
45-
.red
46-
);
47-
}
4848
await cli.parseAsync();
4949
}
5050

0 commit comments

Comments
 (0)