@anmiles/google-api-wrapper 6.0.1 → 6.1.1

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/CHANGELOG.md CHANGED
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [6.1.1](../../tags/v6.1.1) - 2023-03-27
9
+ ### Changed
10
+ - Immediately destroy server after receiving needed response
11
+
12
+ ## [6.1.0](../../tags/v6.1.0) - 2023-03-24
13
+ ### Added
14
+ - Overriding scopes for `getAuth` and `getAPI` functions
15
+
8
16
  ## [6.0.1](../../tags/v6.0.1) - 2023-03-20
9
17
  ### Changed
10
18
  - Improved types for `getItems` method
@@ -14,7 +14,7 @@ export default _default;
14
14
  declare function getScopes(): string[];
15
15
  declare function getSecrets(profile: string): Secrets;
16
16
  declare function getCredentials(profile: string, auth: GoogleApis.Common.OAuth2Client, options?: AuthOptions): Promise<GoogleApis.Auth.Credentials>;
17
- declare function createCredentials(profile: string, auth: GoogleApis.Auth.OAuth2Client): Promise<GoogleApis.Auth.Credentials>;
17
+ declare function createCredentials(profile: string, auth: GoogleApis.Auth.OAuth2Client, options?: AuthOptions): Promise<GoogleApis.Auth.Credentials>;
18
18
  declare function checkSecrets(profile: string, secretsObject: Secrets, secretsFile: string): true | void;
19
19
  declare function getScopesError(scopesFile: string): string;
20
20
  declare function getSecretsError(profile: string, secretsFile: string): string;
@@ -28,6 +28,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.getCredentials = exports.getSecrets = void 0;
30
30
  const http_1 = __importDefault(require("http"));
31
+ const server_destroy_1 = __importDefault(require("server-destroy"));
31
32
  const colorette = __importStar(require("colorette"));
32
33
  const jsonLib_1 = require("./jsonLib");
33
34
  const logger_1 = require("./logger");
@@ -51,12 +52,12 @@ exports.getSecrets = getSecrets;
51
52
  async function getCredentials(profile, auth, options) {
52
53
  const credentialsFile = (0, paths_1.getCredentialsFile)(profile);
53
54
  return (options === null || options === void 0 ? void 0 : options.temporary)
54
- ? secrets_1.default.createCredentials(profile, auth)
55
- : (0, jsonLib_1.getJSONAsync)(credentialsFile, () => secrets_1.default.createCredentials(profile, auth));
55
+ ? secrets_1.default.createCredentials(profile, auth, options)
56
+ : (0, jsonLib_1.getJSONAsync)(credentialsFile, () => secrets_1.default.createCredentials(profile, auth, options));
56
57
  }
57
58
  exports.getCredentials = getCredentials;
58
- async function createCredentials(profile, auth) {
59
- const scope = secrets_1.default.getScopes();
59
+ async function createCredentials(profile, auth, options) {
60
+ const scope = (options === null || options === void 0 ? void 0 : options.scopes) || secrets_1.default.getScopes();
60
61
  return new Promise((resolve) => {
61
62
  const authUrl = auth.generateAuthUrl({
62
63
  // eslint-disable-next-line camelcase
@@ -71,11 +72,12 @@ async function createCredentials(profile, auth) {
71
72
  if (!code) {
72
73
  return;
73
74
  }
74
- server.close();
75
+ server.destroy();
75
76
  const { tokens } = await auth.getToken(code);
76
77
  resolve(tokens);
77
78
  }
78
79
  });
80
+ (0, server_destroy_1.default)(server);
79
81
  server.listen(callbackPort);
80
82
  (0, logger_1.info)(`Please open ${colorette.yellow(authUrl)} in your browser using google profile for ${colorette.yellow(profile)} and allow access to ${colorette.yellow(scope.join(','))}`);
81
83
  });
@@ -1 +1 @@
1
- {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/lib/secrets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/lib/secrets.ts"],"names":[],"mappings":"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"}
@@ -11,4 +11,5 @@ export interface Secrets {
11
11
  }
12
12
  export interface AuthOptions {
13
13
  temporary?: boolean;
14
+ scopes?: string[];
14
15
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anmiles/google-api-wrapper",
3
- "version": "6.0.1",
3
+ "version": "6.1.1",
4
4
  "description": "Provides quick interface for getting google API data",
5
5
  "keywords": [
6
6
  "google",
@@ -31,10 +31,12 @@
31
31
  "dependencies": {
32
32
  "colorette": "^2.0.19",
33
33
  "execa": "^5.1.1",
34
- "googleapis": "^104.0.0"
34
+ "googleapis": "^104.0.0",
35
+ "server-destroy": "^1.0.1"
35
36
  },
36
37
  "devDependencies": {
37
38
  "@types/jest": "^28.1.3",
39
+ "@types/server-destroy": "^1.0.1",
38
40
  "@typescript-eslint/eslint-plugin": "^5.30.0",
39
41
  "@typescript-eslint/parser": "^5.30.0",
40
42
  "eslint": "^8.18.0",
@@ -23,8 +23,10 @@ jest.mock<Partial<typeof http>>('http', () => ({
23
23
  serverCallback = callback;
24
24
 
25
25
  return {
26
+ on,
26
27
  listen,
27
28
  close,
29
+ destroy,
28
30
  };
29
31
  }),
30
32
  }));
@@ -103,10 +105,24 @@ let serverCallback: (
103
105
 
104
106
  let closedTime: number;
105
107
 
108
+ const on = jest.fn().mockImplementation((event: string, listener: (...args: any[]) => void) => {
109
+ if (event === 'connection') {
110
+ // always simulate opening several connections once connections are meant to be listened
111
+ connections.forEach((connection) => listener(connection));
112
+ }
113
+ });
114
+
106
115
  const listen = jest.fn();
107
116
  const close = jest.fn().mockImplementation(() => {
108
117
  closedTime = new Date().getTime();
109
118
  });
119
+ const destroy = jest.fn();
120
+
121
+ const connections = [
122
+ { remoteAddress : 'server', remotePort : '1001', on : jest.fn(), destroy : jest.fn() },
123
+ { remoteAddress : 'server', remotePort : '1002', on : jest.fn(), destroy : jest.fn() },
124
+ { remoteAddress : 'server', remotePort : '1003', on : jest.fn(), destroy : jest.fn() },
125
+ ];
110
126
 
111
127
  describe('src/lib/secrets', () => {
112
128
  describe('getScopes', () => {
@@ -202,7 +218,7 @@ describe('src/lib/secrets', () => {
202
218
  const fallback = getJSONAsyncSpy.mock.calls[0][1];
203
219
  await fallback();
204
220
 
205
- expect(secrets.createCredentials).toBeCalledWith(profile, auth);
221
+ expect(secrets.createCredentials).toBeCalledWith(profile, auth, undefined);
206
222
  });
207
223
 
208
224
  it('should call createCredentials directly if temporariness explicitly unset', async () => {
@@ -211,13 +227,13 @@ describe('src/lib/secrets', () => {
211
227
  const fallback = getJSONAsyncSpy.mock.calls[0][1];
212
228
  await fallback();
213
229
 
214
- expect(secrets.createCredentials).toBeCalledWith(profile, auth);
230
+ expect(secrets.createCredentials).toBeCalledWith(profile, auth, { temporary : false });
215
231
  });
216
232
 
217
233
  it('should call createCredentials directly if temporariness set', async () => {
218
234
  await original.getCredentials(profile, auth, { temporary : true });
219
235
 
220
- expect(secrets.createCredentials).toBeCalledWith(profile, auth);
236
+ expect(secrets.createCredentials).toBeCalledWith(profile, auth, { temporary : true });
221
237
  });
222
238
 
223
239
  it('should return credentials by default', async () => {
@@ -270,6 +286,18 @@ describe('src/lib/secrets', () => {
270
286
  });
271
287
  });
272
288
 
289
+ it('should generate authUrl with custom scopes', async () => {
290
+ willOpen(request, 100);
291
+
292
+ await original.createCredentials(profile, auth, { scopes : [ 'scope1', 'scope2' ] });
293
+
294
+ expect(auth.generateAuthUrl).toBeCalledWith({
295
+ // eslint-disable-next-line camelcase
296
+ access_type : 'offline',
297
+ scope : [ 'scope1', 'scope2' ],
298
+ });
299
+ });
300
+
273
301
  it('should create server on 6006 port', async () => {
274
302
  willOpen(request, 100);
275
303
 
@@ -287,6 +315,14 @@ describe('src/lib/secrets', () => {
287
315
  expect(logger.info).toBeCalledWith(`Please open yellow:https://authUrl in your browser using google profile for yellow:${profile} and allow access to yellow:https://www.googleapis.com/auth/calendar.calendars.readonly,https://www.googleapis.com/auth/calendar.events.readonly`);
288
316
  });
289
317
 
318
+ it('should ask to open browser page with custom scopes', async () => {
319
+ willOpen(request, 100);
320
+
321
+ await original.createCredentials(profile, auth, { scopes : [ 'scope1', 'scope2' ] });
322
+
323
+ expect(logger.info).toBeCalledWith(`Please open yellow:https://authUrl in your browser using google profile for yellow:${profile} and allow access to yellow:scope1,scope2`);
324
+ });
325
+
290
326
  it('should ask to close webpage', async () => {
291
327
  willOpen(request, 100);
292
328
 
@@ -295,12 +331,14 @@ describe('src/lib/secrets', () => {
295
331
  expect(response.end).toBeCalledWith('<h1>Please close this page and return to application. Wait for application to be finished automatically.</h1>');
296
332
  });
297
333
 
298
- it('should close server if request.url is truthy', async () => {
334
+ it('should close server and destroy all connections if request.url is truthy', async () => {
299
335
  willOpen(request, 100);
300
336
 
301
337
  await original.createCredentials(profile, auth);
302
338
 
303
339
  expect(close).toBeCalled();
340
+
341
+ connections.forEach((connection) => expect(connection.destroy).toBeCalled());
304
342
  });
305
343
 
306
344
  it('should only resolve when request.url is truthy', async () => {
@@ -1,4 +1,5 @@
1
1
  import http from 'http';
2
+ import enableDestroy from 'server-destroy';
2
3
  import * as colorette from 'colorette';
3
4
  import type GoogleApis from 'googleapis';
4
5
  import type { Secrets, AuthOptions } from '../types';
@@ -31,12 +32,12 @@ async function getCredentials(profile: string, auth: GoogleApis.Common.OAuth2Cli
31
32
  const credentialsFile = getCredentialsFile(profile);
32
33
 
33
34
  return options?.temporary
34
- ? secrets.createCredentials(profile, auth)
35
- : getJSONAsync(credentialsFile, () => secrets.createCredentials(profile, auth));
35
+ ? secrets.createCredentials(profile, auth, options)
36
+ : getJSONAsync(credentialsFile, () => secrets.createCredentials(profile, auth, options));
36
37
  }
37
38
 
38
- async function createCredentials(profile: string, auth: GoogleApis.Auth.OAuth2Client): Promise<GoogleApis.Auth.Credentials> {
39
- const scope = secrets.getScopes();
39
+ async function createCredentials(profile: string, auth: GoogleApis.Auth.OAuth2Client, options?: AuthOptions): Promise<GoogleApis.Auth.Credentials> {
40
+ const scope = options?.scopes || secrets.getScopes();
40
41
 
41
42
  return new Promise((resolve) => {
42
43
  const authUrl = auth.generateAuthUrl({
@@ -56,12 +57,13 @@ async function createCredentials(profile: string, auth: GoogleApis.Auth.OAuth2Cl
56
57
  return;
57
58
  }
58
59
 
59
- server.close();
60
+ server.destroy();
60
61
  const { tokens } = await auth.getToken(code);
61
62
  resolve(tokens);
62
63
  }
63
64
  });
64
65
 
66
+ enableDestroy(server);
65
67
  server.listen(callbackPort);
66
68
  info(`Please open ${colorette.yellow(authUrl)} in your browser using google profile for ${colorette.yellow(profile)} and allow access to ${colorette.yellow(scope.join(','))}`);
67
69
  });
@@ -11,6 +11,7 @@ export interface Secrets {
11
11
  }
12
12
 
13
13
  export interface AuthOptions {
14
- temporary?: boolean
14
+ temporary?: boolean;
15
+ scopes?: string[];
15
16
  }
16
17