@anmiles/google-api-wrapper 7.0.6 → 8.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/.eslintrc.js +1 -86
- package/.gitlab-ci.yml +0 -1
- package/.vscode/settings.json +0 -4
- package/CHANGELOG.md +11 -0
- package/README.md +5 -2
- package/dist/index.d.ts +5 -5
- package/dist/index.js +15 -15
- package/dist/lib/api/calendar.d.ts +3 -3
- package/dist/lib/api/calendar.js +13 -13
- package/dist/lib/api/shared.d.ts +23 -23
- package/dist/lib/api/shared.js +26 -23
- package/dist/lib/api/shared.js.map +1 -1
- package/dist/lib/api/youtube.d.ts +3 -3
- package/dist/lib/api/youtube.js +13 -13
- package/dist/lib/auth.d.ts +10 -10
- package/dist/lib/auth.js +34 -34
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/paths.d.ts +12 -16
- package/dist/lib/paths.js +28 -45
- package/dist/lib/paths.js.map +1 -1
- package/dist/lib/profiles.d.ts +11 -10
- package/dist/lib/profiles.js +33 -33
- package/dist/lib/profiles.js.map +1 -1
- package/dist/lib/secrets.d.ts +26 -22
- package/dist/lib/secrets.js +152 -146
- package/dist/lib/secrets.js.map +1 -1
- package/dist/types/common.d.ts +3 -3
- package/dist/types/common.js +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +18 -18
- package/dist/types/secrets.d.ts +15 -15
- package/dist/types/secrets.js +2 -2
- package/package.json +18 -15
- package/src/lib/__tests__/auth.test.ts +23 -23
- package/src/lib/__tests__/paths.test.ts +1 -63
- package/src/lib/__tests__/profiles.test.ts +25 -21
- package/src/lib/__tests__/secrets.test.ts +100 -94
- package/src/lib/api/__tests__/calendar.test.ts +3 -3
- package/src/lib/api/__tests__/shared.test.ts +12 -14
- package/src/lib/api/__tests__/youtube.test.ts +3 -3
- package/src/lib/api/shared.ts +2 -2
- package/src/lib/auth.ts +1 -1
- package/src/lib/paths.ts +2 -20
- package/src/lib/profiles.ts +5 -5
- package/src/lib/secrets.ts +24 -17
- package/dist/lib/jsonLib.d.ts +0 -14
- package/dist/lib/jsonLib.js +0 -56
- package/dist/lib/jsonLib.js.map +0 -1
- package/dist/lib/logger.d.ts +0 -12
- package/dist/lib/logger.js +0 -46
- package/dist/lib/logger.js.map +0 -1
- package/dist/lib/sleep.d.ts +0 -6
- package/dist/lib/sleep.js +0 -11
- package/dist/lib/sleep.js.map +0 -1
- package/src/lib/__tests__/jsonLib.test.ts +0 -253
- package/src/lib/__tests__/logger.test.ts +0 -57
- package/src/lib/__tests__/sleep.test.ts +0 -17
- package/src/lib/jsonLib.ts +0 -57
- package/src/lib/logger.ts +0 -21
- package/src/lib/sleep.ts +0 -8
package/src/lib/secrets.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
1
2
|
import http from 'http';
|
|
2
3
|
import enableDestroy from 'server-destroy';
|
|
3
4
|
import open from 'open';
|
|
4
5
|
import type GoogleApis from 'googleapis';
|
|
6
|
+
import { warn } from '@anmiles/logger';
|
|
5
7
|
import type { Secrets, AuthOptions } from '../types';
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import { getScopesFile, getSecretsFile, getCredentialsFile, ensureFile } from './paths';
|
|
8
|
+
import '@anmiles/prototypes';
|
|
9
|
+
import { getScopesFile, getSecretsFile, getCredentialsFile } from './paths';
|
|
9
10
|
|
|
10
11
|
import secrets from './secrets';
|
|
11
12
|
|
|
@@ -19,13 +20,17 @@ const tokenExpiration = 7 * 24 * 60 * 60 * 1000;
|
|
|
19
20
|
|
|
20
21
|
function getScopes(): string[] {
|
|
21
22
|
const scopesFile = getScopesFile();
|
|
22
|
-
const scopes = getJSON<string[]>(scopesFile, () =>
|
|
23
|
+
const scopes = fs.getJSON<string[]>(scopesFile, () => {
|
|
24
|
+
throw secrets.getScopesError(scopesFile);
|
|
25
|
+
});
|
|
23
26
|
return scopes;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
function getSecrets(profile: string): Secrets {
|
|
27
30
|
const secretsFile = getSecretsFile(profile);
|
|
28
|
-
const secretsObject = getJSON<Secrets>(secretsFile, () =>
|
|
31
|
+
const secretsObject = fs.getJSON<Secrets>(secretsFile, () => {
|
|
32
|
+
throw secrets.getSecretsError(profile, secretsFile);
|
|
33
|
+
});
|
|
29
34
|
secrets.checkSecrets(profile, secretsObject, secretsFile);
|
|
30
35
|
return secretsObject;
|
|
31
36
|
}
|
|
@@ -37,30 +42,32 @@ async function getCredentials(profile: string, auth: GoogleApis.Common.OAuth2Cli
|
|
|
37
42
|
return secrets.createCredentials(profile, auth, options);
|
|
38
43
|
}
|
|
39
44
|
|
|
40
|
-
return getJSONAsync(credentialsFile, async () => {
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
// eslint-disable-next-line camelcase
|
|
44
|
-
const credentials = await secrets.createCredentials(profile, auth, options, refresh_token ? undefined : 'consent');
|
|
45
|
+
return fs.getJSONAsync(credentialsFile, async () => {
|
|
46
|
+
const refreshToken = fs.existsSync(credentialsFile) ? fs.readJSON<GoogleApis.Auth.Credentials>(credentialsFile).refresh_token : undefined;
|
|
47
|
+
const credentials = await secrets.createCredentials(profile, auth, options, refreshToken ? undefined : 'consent');
|
|
45
48
|
// eslint-disable-next-line camelcase
|
|
46
|
-
return { refresh_token, ...credentials };
|
|
49
|
+
return { refresh_token : refreshToken, ...credentials };
|
|
47
50
|
}, secrets.validateCredentials);
|
|
48
51
|
}
|
|
49
52
|
|
|
50
|
-
async function validateCredentials(credentials: GoogleApis.Auth.Credentials): Promise<boolean> {
|
|
53
|
+
async function validateCredentials(credentials: GoogleApis.Auth.Credentials): Promise<{ isValid: boolean, validationError?: string}> {
|
|
51
54
|
if (!credentials.access_token) {
|
|
52
|
-
return false;
|
|
55
|
+
return { isValid : false, validationError : 'Credentials does not have access_token' };
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
if (!credentials.refresh_token) {
|
|
56
|
-
return false;
|
|
59
|
+
return { isValid : false, validationError : 'Credentials does not have refresh_token' };
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
if (!credentials.expiry_date) {
|
|
60
|
-
return
|
|
63
|
+
return { isValid : false, validationError : 'Credentials does not have expiry_date' };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (new Date().getTime() - credentials.expiry_date >= tokenExpiration) {
|
|
67
|
+
return { isValid : false, validationError : 'Credentials expired' };
|
|
61
68
|
}
|
|
62
69
|
|
|
63
|
-
return
|
|
70
|
+
return { isValid : true };
|
|
64
71
|
}
|
|
65
72
|
|
|
66
73
|
async function createCredentials(profile: string, auth: GoogleApis.Auth.OAuth2Client, options?: AuthOptions, prompt?: GoogleApis.Auth.GenerateAuthUrlOpts['prompt']): Promise<GoogleApis.Auth.Credentials> {
|
|
@@ -116,7 +123,7 @@ function checkSecrets(profile: string, secretsObject: Secrets, secretsFile: stri
|
|
|
116
123
|
if (secretsObject.web.redirect_uris[0] === callbackURI) {
|
|
117
124
|
return true;
|
|
118
125
|
}
|
|
119
|
-
|
|
126
|
+
throw `Error in credentials file: redirect URI should be ${callbackURI}.\n${secrets.getSecretsError(profile, secretsFile)}`;
|
|
120
127
|
}
|
|
121
128
|
|
|
122
129
|
function getScopesError(scopesFile: string) {
|
package/dist/lib/jsonLib.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export { getJSON, getJSONAsync, writeJSON, readJSON };
|
|
2
|
-
declare const _default: {
|
|
3
|
-
getJSON: typeof getJSON;
|
|
4
|
-
getJSONAsync: typeof getJSONAsync;
|
|
5
|
-
writeJSON: typeof writeJSON;
|
|
6
|
-
readJSON: typeof readJSON;
|
|
7
|
-
checkJSON: typeof checkJSON;
|
|
8
|
-
};
|
|
9
|
-
export default _default;
|
|
10
|
-
declare function getJSON<T>(filename: string, createCallback: () => Exclude<T, Promise<any>>, validateJSON?: (json: T) => boolean): T;
|
|
11
|
-
declare function getJSONAsync<T>(filename: string, createCallbackAsync: () => Promise<T>, validateJSONAsync?: (json: T) => Promise<boolean>): Promise<T>;
|
|
12
|
-
declare function writeJSON<T>(filename: string, json: T): void;
|
|
13
|
-
declare function readJSON<T>(filename: string): T;
|
|
14
|
-
declare function checkJSON<T>(filename: string, json: T): void;
|
package/dist/lib/jsonLib.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
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.readJSON = exports.writeJSON = exports.getJSONAsync = exports.getJSON = void 0;
|
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
const logger_1 = require("./logger");
|
|
9
|
-
const paths_1 = require("./paths");
|
|
10
|
-
const jsonLib_1 = __importDefault(require("./jsonLib"));
|
|
11
|
-
exports.default = { getJSON, getJSONAsync, writeJSON, readJSON, checkJSON };
|
|
12
|
-
function getJSON(filename, createCallback, validateJSON) {
|
|
13
|
-
if (fs_1.default.existsSync(filename)) {
|
|
14
|
-
const json = jsonLib_1.default.readJSON(filename);
|
|
15
|
-
if (!validateJSON || validateJSON(json)) {
|
|
16
|
-
return json;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
const json = createCallback();
|
|
20
|
-
jsonLib_1.default.checkJSON(filename, json);
|
|
21
|
-
(0, paths_1.ensureFile)(filename);
|
|
22
|
-
jsonLib_1.default.writeJSON(filename, json);
|
|
23
|
-
return json;
|
|
24
|
-
}
|
|
25
|
-
exports.getJSON = getJSON;
|
|
26
|
-
async function getJSONAsync(filename, createCallbackAsync, validateJSONAsync) {
|
|
27
|
-
if (fs_1.default.existsSync(filename)) {
|
|
28
|
-
const json = jsonLib_1.default.readJSON(filename);
|
|
29
|
-
if (!validateJSONAsync || await validateJSONAsync(json)) {
|
|
30
|
-
return json;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
const json = await createCallbackAsync();
|
|
34
|
-
jsonLib_1.default.checkJSON(filename, json);
|
|
35
|
-
(0, paths_1.ensureFile)(filename);
|
|
36
|
-
jsonLib_1.default.writeJSON(filename, json);
|
|
37
|
-
return json;
|
|
38
|
-
}
|
|
39
|
-
exports.getJSONAsync = getJSONAsync;
|
|
40
|
-
function writeJSON(filename, json) {
|
|
41
|
-
const jsonString = JSON.stringify(json, null, ' ');
|
|
42
|
-
fs_1.default.writeFileSync(filename, jsonString);
|
|
43
|
-
}
|
|
44
|
-
exports.writeJSON = writeJSON;
|
|
45
|
-
function readJSON(filename) {
|
|
46
|
-
const jsonString = fs_1.default.readFileSync(filename).toString();
|
|
47
|
-
return JSON.parse(jsonString);
|
|
48
|
-
}
|
|
49
|
-
exports.readJSON = readJSON;
|
|
50
|
-
function checkJSON(filename, json) {
|
|
51
|
-
if (json) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
(0, logger_1.error)(`File ${filename} doesn't exist and should be created with initial data, but function createCallback returned nothing`);
|
|
55
|
-
}
|
|
56
|
-
//# sourceMappingURL=jsonLib.js.map
|
package/dist/lib/jsonLib.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jsonLib.js","sourceRoot":"","sources":["../../src/lib/jsonLib.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,qCAAiC;AACjC,mCAAqC;AAErC,wDAAgC;AAGhC,kBAAe,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAEzE,SAAS,OAAO,CAAI,QAAgB,EAAE,cAA8C,EAAE,YAAmC;IACxH,IAAI,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;QAC5B,MAAM,IAAI,GAAG,iBAAO,CAAC,QAAQ,CAAI,QAAQ,CAAC,CAAC;QAE3C,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE;YACxC,OAAO,IAAI,CAAC;SACZ;KACD;IAED,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,iBAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClC,IAAA,kBAAU,EAAC,QAAQ,CAAC,CAAC;IACrB,iBAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClC,OAAO,IAAI,CAAC;AACb,CAAC;AAjBQ,0BAAO;AAmBhB,KAAK,UAAU,YAAY,CAAI,QAAgB,EAAE,mBAAqC,EAAE,iBAAiD;IACxI,IAAI,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;QAC5B,MAAM,IAAI,GAAG,iBAAO,CAAC,QAAQ,CAAI,QAAQ,CAAC,CAAC;QAE3C,IAAI,CAAC,iBAAiB,IAAI,MAAM,iBAAiB,CAAC,IAAI,CAAC,EAAE;YACxD,OAAO,IAAI,CAAC;SACZ;KACD;IAED,MAAM,IAAI,GAAG,MAAM,mBAAmB,EAAE,CAAC;IACzC,iBAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClC,IAAA,kBAAU,EAAC,QAAQ,CAAC,CAAC;IACrB,iBAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClC,OAAO,IAAI,CAAC;AACb,CAAC;AAjCiB,oCAAY;AAmC9B,SAAS,SAAS,CAAI,QAAgB,EAAE,IAAO;IAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACtD,YAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;AACxC,CAAC;AAtC+B,8BAAS;AAwCzC,SAAS,QAAQ,CAAI,QAAgB;IACpC,MAAM,UAAU,GAAG,YAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxD,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAM,CAAC;AACpC,CAAC;AA3C0C,4BAAQ;AA6CnD,SAAS,SAAS,CAAI,QAAgB,EAAE,IAAO;IAC9C,IAAI,IAAI,EAAE;QACT,OAAO;KACP;IACD,IAAA,cAAK,EAAC,QAAQ,QAAQ,sGAAsG,CAAC,CAAC;AAC/H,CAAC"}
|
package/dist/lib/logger.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export { log, info, warn, error };
|
|
2
|
-
declare const _default: {
|
|
3
|
-
log: typeof log;
|
|
4
|
-
info: typeof info;
|
|
5
|
-
warn: typeof warn;
|
|
6
|
-
error: typeof error;
|
|
7
|
-
};
|
|
8
|
-
export default _default;
|
|
9
|
-
declare function log(message: string): void;
|
|
10
|
-
declare function info(message: string): void;
|
|
11
|
-
declare function warn(message: string): void;
|
|
12
|
-
declare function error(message: string): never;
|
package/dist/lib/logger.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.error = exports.warn = exports.info = exports.log = void 0;
|
|
27
|
-
const colorette = __importStar(require("colorette"));
|
|
28
|
-
exports.default = { log, info, warn, error };
|
|
29
|
-
function log(message) {
|
|
30
|
-
console.log(message);
|
|
31
|
-
}
|
|
32
|
-
exports.log = log;
|
|
33
|
-
function info(message) {
|
|
34
|
-
console.log(colorette.greenBright(message));
|
|
35
|
-
}
|
|
36
|
-
exports.info = info;
|
|
37
|
-
function warn(message) {
|
|
38
|
-
console.warn(colorette.yellowBright(message));
|
|
39
|
-
}
|
|
40
|
-
exports.warn = warn;
|
|
41
|
-
function error(message) {
|
|
42
|
-
console.error(`${colorette.redBright(message)}\n`);
|
|
43
|
-
process.exit(1);
|
|
44
|
-
}
|
|
45
|
-
exports.error = error;
|
|
46
|
-
//# sourceMappingURL=logger.js.map
|
package/dist/lib/logger.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qDAAuC;AAGvC,kBAAe,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAE1C,SAAS,GAAG,CAAC,OAAe;IAC3B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACtB,CAAC;AALQ,kBAAG;AAOZ,SAAS,IAAI,CAAC,OAAe;IAC5B,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7C,CAAC;AATa,oBAAI;AAWlB,SAAS,IAAI,CAAC,OAAe;IAC5B,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;AAC/C,CAAC;AAbmB,oBAAI;AAexB,SAAS,KAAK,CAAC,OAAe;IAC7B,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAlByB,sBAAK"}
|
package/dist/lib/sleep.d.ts
DELETED
package/dist/lib/sleep.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sleep = void 0;
|
|
4
|
-
exports.default = { sleep };
|
|
5
|
-
async function sleep(milliSeconds) {
|
|
6
|
-
return new Promise((resolve) => {
|
|
7
|
-
setTimeout(resolve, milliSeconds);
|
|
8
|
-
});
|
|
9
|
-
}
|
|
10
|
-
exports.sleep = sleep;
|
|
11
|
-
//# sourceMappingURL=sleep.js.map
|
package/dist/lib/sleep.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../src/lib/sleep.ts"],"names":[],"mappings":";;;AACA,kBAAe,EAAE,KAAK,EAAE,CAAC;AAEzB,KAAK,UAAU,KAAK,CAAC,YAAoB;IACxC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACJ,CAAC;AAPQ,sBAAK"}
|
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import logger from '../logger';
|
|
3
|
-
import paths from '../paths';
|
|
4
|
-
|
|
5
|
-
import jsonLib from '../jsonLib';
|
|
6
|
-
const original = jest.requireActual('../jsonLib').default as typeof jsonLib;
|
|
7
|
-
jest.mock<typeof jsonLib>('../jsonLib', () => ({
|
|
8
|
-
readJSON : jest.fn().mockImplementation(() => json),
|
|
9
|
-
writeJSON : jest.fn(),
|
|
10
|
-
getJSON : jest.fn(),
|
|
11
|
-
getJSONAsync : jest.fn(),
|
|
12
|
-
checkJSON : jest.fn(),
|
|
13
|
-
}));
|
|
14
|
-
|
|
15
|
-
jest.mock<Partial<typeof fs>>('fs', () => ({
|
|
16
|
-
readFileSync : jest.fn().mockImplementation(() => jsonString),
|
|
17
|
-
writeFileSync : jest.fn(),
|
|
18
|
-
existsSync : jest.fn().mockImplementation(() => fileExists),
|
|
19
|
-
}));
|
|
20
|
-
|
|
21
|
-
jest.mock<Partial<typeof logger>>('../logger', () => ({
|
|
22
|
-
error : jest.fn().mockImplementation((error) => {
|
|
23
|
-
throw error;
|
|
24
|
-
}) as jest.Mock<never, any>,
|
|
25
|
-
}));
|
|
26
|
-
|
|
27
|
-
jest.mock<Partial<typeof paths>>('../paths', () => ({
|
|
28
|
-
ensureFile : jest.fn(),
|
|
29
|
-
}));
|
|
30
|
-
|
|
31
|
-
const filename = 'filename';
|
|
32
|
-
const json = { key : 'value' };
|
|
33
|
-
const jsonString = JSON.stringify(json, null, ' ');
|
|
34
|
-
const fallbackJSON = { fallbackKey : 'fallbackValue' };
|
|
35
|
-
|
|
36
|
-
let fileExists: boolean;
|
|
37
|
-
let validation: boolean;
|
|
38
|
-
|
|
39
|
-
const validateCallback = jest.fn().mockImplementation(() => validation);
|
|
40
|
-
const validateCallbackAsync = jest.fn().mockImplementation(async () => validation);
|
|
41
|
-
|
|
42
|
-
const createCallback = jest.fn().mockReturnValue(fallbackJSON);
|
|
43
|
-
const createCallbackAsync = jest.fn().mockResolvedValue(fallbackJSON);
|
|
44
|
-
|
|
45
|
-
describe('src/lib/jsonLib', () => {
|
|
46
|
-
describe('readJSON', () => {
|
|
47
|
-
it('should read specified file', () => {
|
|
48
|
-
original.readJSON(filename);
|
|
49
|
-
|
|
50
|
-
expect(fs.readFileSync).toBeCalledWith(filename);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('should return parsed JSON', () => {
|
|
54
|
-
const result = original.readJSON(filename);
|
|
55
|
-
|
|
56
|
-
expect(result).toEqual(json);
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
describe('writeJSON', () => {
|
|
61
|
-
it('should write JSON into specified file', () => {
|
|
62
|
-
original.writeJSON(filename, json);
|
|
63
|
-
|
|
64
|
-
expect(fs.writeFileSync).toBeCalledWith(filename, jsonString);
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
describe('getJSON', () => {
|
|
69
|
-
|
|
70
|
-
it('should call readJSON if file exists and json is valid', () => {
|
|
71
|
-
fileExists = true;
|
|
72
|
-
validation = true;
|
|
73
|
-
|
|
74
|
-
original.getJSON(filename, createCallback, validateCallback);
|
|
75
|
-
|
|
76
|
-
expect(jsonLib.readJSON).toBeCalledWith(filename);
|
|
77
|
-
expect(createCallback).not.toBeCalled();
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should call createCallback if file exists but json is not valid', () => {
|
|
81
|
-
fileExists = true;
|
|
82
|
-
validation = false;
|
|
83
|
-
|
|
84
|
-
original.getJSON(filename, createCallback, validateCallback);
|
|
85
|
-
|
|
86
|
-
expect(jsonLib.readJSON).toBeCalledWith(filename);
|
|
87
|
-
expect(createCallback).toBeCalledWith();
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('should call createCallback if file not exists', () => {
|
|
91
|
-
fileExists = false;
|
|
92
|
-
|
|
93
|
-
original.getJSON(filename, createCallback, validateCallback);
|
|
94
|
-
|
|
95
|
-
expect(jsonLib.readJSON).not.toBeCalled();
|
|
96
|
-
expect(createCallback).toBeCalledWith();
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it('should not write fallback JSON back if file exists and json is valid', () => {
|
|
100
|
-
fileExists = true;
|
|
101
|
-
validation = true;
|
|
102
|
-
|
|
103
|
-
original.getJSON(filename, createCallback, validateCallback);
|
|
104
|
-
|
|
105
|
-
expect(jsonLib.writeJSON).not.toBeCalled();
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('should write fallback JSON back if file exists but json is not valid', () => {
|
|
109
|
-
fileExists = true;
|
|
110
|
-
validation = false;
|
|
111
|
-
|
|
112
|
-
original.getJSON(filename, createCallback, validateCallback);
|
|
113
|
-
|
|
114
|
-
expect(jsonLib.checkJSON).toBeCalledWith(filename, fallbackJSON);
|
|
115
|
-
expect(paths.ensureFile).toBeCalledWith(filename);
|
|
116
|
-
expect(jsonLib.writeJSON).toBeCalledWith(filename, fallbackJSON);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it('should write fallback JSON back if file not exists', () => {
|
|
120
|
-
fileExists = false;
|
|
121
|
-
|
|
122
|
-
original.getJSON(filename, createCallback, validateCallback);
|
|
123
|
-
|
|
124
|
-
expect(jsonLib.checkJSON).toBeCalledWith(filename, fallbackJSON);
|
|
125
|
-
expect(paths.ensureFile).toBeCalledWith(filename);
|
|
126
|
-
expect(jsonLib.writeJSON).toBeCalledWith(filename, fallbackJSON);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should return JSON if file exists and json is valid', () => {
|
|
130
|
-
fileExists = true;
|
|
131
|
-
validation = true;
|
|
132
|
-
|
|
133
|
-
const result = original.getJSON(filename, createCallback, validateCallback);
|
|
134
|
-
|
|
135
|
-
expect(result).toEqual(json);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it('should return fallback JSON if file exists but json is not valid', () => {
|
|
139
|
-
fileExists = true;
|
|
140
|
-
validation = false;
|
|
141
|
-
|
|
142
|
-
const result = original.getJSON(filename, createCallback, validateCallback);
|
|
143
|
-
|
|
144
|
-
expect(result).toEqual(fallbackJSON);
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
it('should return fallback JSON if file not exists', () => {
|
|
148
|
-
fileExists = false;
|
|
149
|
-
|
|
150
|
-
const result = original.getJSON(filename, createCallback, validateCallback);
|
|
151
|
-
|
|
152
|
-
expect(result).toEqual(fallbackJSON);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
describe('getJSONAsync', () => {
|
|
157
|
-
it('should call readJSON if file exists and json is valid', async () => {
|
|
158
|
-
fileExists = true;
|
|
159
|
-
validation = true;
|
|
160
|
-
|
|
161
|
-
await original.getJSONAsync(filename, createCallbackAsync, validateCallbackAsync);
|
|
162
|
-
|
|
163
|
-
expect(jsonLib.readJSON).toBeCalledWith(filename);
|
|
164
|
-
expect(createCallbackAsync).not.toBeCalled();
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('should call createCallback if file exists but json is not valid', async () => {
|
|
168
|
-
fileExists = true;
|
|
169
|
-
validation = false;
|
|
170
|
-
|
|
171
|
-
await original.getJSONAsync(filename, createCallbackAsync, validateCallbackAsync);
|
|
172
|
-
|
|
173
|
-
expect(jsonLib.readJSON).toBeCalledWith(filename);
|
|
174
|
-
expect(createCallbackAsync).toBeCalledWith();
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it('should call createCallback if file not exists', async () => {
|
|
178
|
-
fileExists = false;
|
|
179
|
-
|
|
180
|
-
await original.getJSONAsync(filename, createCallbackAsync, validateCallbackAsync);
|
|
181
|
-
|
|
182
|
-
expect(jsonLib.readJSON).not.toBeCalled();
|
|
183
|
-
expect(createCallbackAsync).toBeCalledWith();
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
it('should not write fallback JSON back if file exists and json is valid', async () => {
|
|
187
|
-
fileExists = true;
|
|
188
|
-
validation = true;
|
|
189
|
-
|
|
190
|
-
await original.getJSONAsync(filename, createCallbackAsync, validateCallbackAsync);
|
|
191
|
-
|
|
192
|
-
expect(jsonLib.writeJSON).not.toBeCalled();
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
it('should write fallback JSON back if file exists but json is not valid', async () => {
|
|
196
|
-
fileExists = true;
|
|
197
|
-
validation = false;
|
|
198
|
-
|
|
199
|
-
await original.getJSONAsync(filename, createCallbackAsync, validateCallbackAsync);
|
|
200
|
-
|
|
201
|
-
expect(jsonLib.checkJSON).toBeCalledWith(filename, fallbackJSON);
|
|
202
|
-
expect(paths.ensureFile).toBeCalledWith(filename);
|
|
203
|
-
expect(jsonLib.writeJSON).toBeCalledWith(filename, fallbackJSON);
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
it('should write fallback JSON back if file not exists', async () => {
|
|
207
|
-
fileExists = false;
|
|
208
|
-
|
|
209
|
-
await original.getJSONAsync(filename, createCallbackAsync, validateCallbackAsync);
|
|
210
|
-
|
|
211
|
-
expect(jsonLib.checkJSON).toBeCalledWith(filename, fallbackJSON);
|
|
212
|
-
expect(paths.ensureFile).toBeCalledWith(filename);
|
|
213
|
-
expect(jsonLib.writeJSON).toBeCalledWith(filename, fallbackJSON);
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
it('should return JSON if file exists and json is valid', async () => {
|
|
217
|
-
fileExists = true;
|
|
218
|
-
validation = true;
|
|
219
|
-
|
|
220
|
-
const result = await original.getJSONAsync(filename, createCallbackAsync, validateCallbackAsync);
|
|
221
|
-
|
|
222
|
-
expect(result).toEqual(json);
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
it('should return fallback JSON if file exists but json is not valid', async () => {
|
|
226
|
-
fileExists = true;
|
|
227
|
-
validation = false;
|
|
228
|
-
|
|
229
|
-
const result = await original.getJSONAsync(filename, createCallbackAsync, validateCallbackAsync);
|
|
230
|
-
|
|
231
|
-
expect(result).toEqual(fallbackJSON);
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
it('should return fallback JSON if file not exists', async () => {
|
|
235
|
-
fileExists = false;
|
|
236
|
-
|
|
237
|
-
const result = await original.getJSONAsync(filename, createCallbackAsync, validateCallbackAsync);
|
|
238
|
-
|
|
239
|
-
expect(result).toEqual(fallbackJSON);
|
|
240
|
-
});
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
describe('checkJSON', () => {
|
|
244
|
-
it('should do nothing if json is truthy', () => {
|
|
245
|
-
original.checkJSON(filename, json);
|
|
246
|
-
|
|
247
|
-
expect(logger.error).not.toBeCalled();
|
|
248
|
-
});
|
|
249
|
-
it('should output error if json is falsy', () => {
|
|
250
|
-
expect(() => original.checkJSON(filename, '')).toThrowError(`File ${filename} doesn't exist and should be created with initial data, but function createCallback returned nothing`);
|
|
251
|
-
});
|
|
252
|
-
});
|
|
253
|
-
});
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import * as colorette from 'colorette';
|
|
2
|
-
|
|
3
|
-
import logger from '../logger';
|
|
4
|
-
|
|
5
|
-
const text = 'text';
|
|
6
|
-
|
|
7
|
-
const originalConsole = global.console;
|
|
8
|
-
global.console.log = jest.fn();
|
|
9
|
-
global.console.info = jest.fn();
|
|
10
|
-
global.console.warn = jest.fn();
|
|
11
|
-
global.console.error = jest.fn();
|
|
12
|
-
|
|
13
|
-
const exit = jest.spyOn(process, 'exit').mockImplementation();
|
|
14
|
-
|
|
15
|
-
afterAll(() => {
|
|
16
|
-
global.console = originalConsole;
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
describe('src/lib/logger', () => {
|
|
20
|
-
describe('log', () => {
|
|
21
|
-
it('should call console.log with original text', () => {
|
|
22
|
-
logger.log(text);
|
|
23
|
-
|
|
24
|
-
expect(global.console.log).toBeCalledWith(text);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
describe('info', () => {
|
|
29
|
-
it('should call console.info with bright green text', () => {
|
|
30
|
-
logger.info(text);
|
|
31
|
-
|
|
32
|
-
expect(global.console.log).toBeCalledWith(colorette.greenBright(text));
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
describe('warn', () => {
|
|
37
|
-
it('should call console.warn with bright yellow text', () => {
|
|
38
|
-
logger.warn(text);
|
|
39
|
-
|
|
40
|
-
expect(global.console.warn).toBeCalledWith(colorette.yellowBright(text));
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
describe('error', () => {
|
|
45
|
-
it('should call console.error with bright red text and newline', () => {
|
|
46
|
-
logger.error(text);
|
|
47
|
-
|
|
48
|
-
expect(global.console.error).toBeCalledWith(`${colorette.redBright(text)}\n`);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('should exit the process with code 1', () => {
|
|
52
|
-
logger.error(text);
|
|
53
|
-
|
|
54
|
-
expect(exit).toBeCalledWith(1);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import sleep from '../sleep';
|
|
2
|
-
|
|
3
|
-
const sleepMilliseconds = 300;
|
|
4
|
-
|
|
5
|
-
describe('src/lib/sleep', () => {
|
|
6
|
-
describe('sleep', () => {
|
|
7
|
-
|
|
8
|
-
it('should wait specified timeout', async () => {
|
|
9
|
-
const before = new Date().getTime();
|
|
10
|
-
|
|
11
|
-
await sleep.sleep(sleepMilliseconds);
|
|
12
|
-
|
|
13
|
-
const after = new Date().getTime();
|
|
14
|
-
expect(after - before).toBeGreaterThanOrEqual(sleepMilliseconds - 1);
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
});
|
package/src/lib/jsonLib.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import { error } from './logger';
|
|
3
|
-
import { ensureFile } from './paths';
|
|
4
|
-
|
|
5
|
-
import jsonLib from './jsonLib';
|
|
6
|
-
|
|
7
|
-
export { getJSON, getJSONAsync, writeJSON, readJSON };
|
|
8
|
-
export default { getJSON, getJSONAsync, writeJSON, readJSON, checkJSON };
|
|
9
|
-
|
|
10
|
-
function getJSON<T>(filename: string, createCallback: () => Exclude<T, Promise<any>>, validateJSON?: (json: T) => boolean): T {
|
|
11
|
-
if (fs.existsSync(filename)) {
|
|
12
|
-
const json = jsonLib.readJSON<T>(filename);
|
|
13
|
-
|
|
14
|
-
if (!validateJSON || validateJSON(json)) {
|
|
15
|
-
return json;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const json = createCallback();
|
|
20
|
-
jsonLib.checkJSON(filename, json);
|
|
21
|
-
ensureFile(filename);
|
|
22
|
-
jsonLib.writeJSON(filename, json);
|
|
23
|
-
return json;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async function getJSONAsync<T>(filename: string, createCallbackAsync: () => Promise<T>, validateJSONAsync?: (json: T) => Promise<boolean>): Promise<T> {
|
|
27
|
-
if (fs.existsSync(filename)) {
|
|
28
|
-
const json = jsonLib.readJSON<T>(filename);
|
|
29
|
-
|
|
30
|
-
if (!validateJSONAsync || await validateJSONAsync(json)) {
|
|
31
|
-
return json;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const json = await createCallbackAsync();
|
|
36
|
-
jsonLib.checkJSON(filename, json);
|
|
37
|
-
ensureFile(filename);
|
|
38
|
-
jsonLib.writeJSON(filename, json);
|
|
39
|
-
return json;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function writeJSON<T>(filename: string, json: T): void {
|
|
43
|
-
const jsonString = JSON.stringify(json, null, ' ');
|
|
44
|
-
fs.writeFileSync(filename, jsonString);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function readJSON<T>(filename: string): T {
|
|
48
|
-
const jsonString = fs.readFileSync(filename).toString();
|
|
49
|
-
return JSON.parse(jsonString) as T;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function checkJSON<T>(filename: string, json: T): void {
|
|
53
|
-
if (json) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
error(`File ${filename} doesn't exist and should be created with initial data, but function createCallback returned nothing`);
|
|
57
|
-
}
|
package/src/lib/logger.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import * as colorette from 'colorette';
|
|
2
|
-
|
|
3
|
-
export { log, info, warn, error };
|
|
4
|
-
export default { log, info, warn, error };
|
|
5
|
-
|
|
6
|
-
function log(message: string): void {
|
|
7
|
-
console.log(message);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function info(message: string): void {
|
|
11
|
-
console.log(colorette.greenBright(message));
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function warn(message: string): void {
|
|
15
|
-
console.warn(colorette.yellowBright(message));
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function error(message: string): never {
|
|
19
|
-
console.error(`${colorette.redBright(message)}\n`);
|
|
20
|
-
process.exit(1);
|
|
21
|
-
}
|