latchkey 1.0.0 → 2.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/README.md +37 -13
- package/dist/integrations/SKILL.md +9 -2
- package/dist/package.json +1 -1
- package/dist/scripts/codegen/codeGenerator.d.ts +27 -0
- package/dist/scripts/codegen/codeGenerator.d.ts.map +1 -0
- package/dist/scripts/codegen/codeGenerator.js +220 -0
- package/dist/scripts/codegen/codeGenerator.js.map +1 -0
- package/dist/scripts/codegen/index.d.ts +27 -0
- package/dist/scripts/codegen/index.d.ts.map +1 -0
- package/dist/scripts/codegen/index.js +189 -0
- package/dist/scripts/codegen/index.js.map +1 -0
- package/dist/scripts/codegen/injectedScript.d.ts +6 -0
- package/dist/scripts/codegen/injectedScript.d.ts.map +1 -0
- package/dist/scripts/codegen/injectedScript.js +657 -0
- package/dist/scripts/codegen/injectedScript.js.map +1 -0
- package/dist/scripts/codegen/requestMetadataCollector.d.ts +15 -0
- package/dist/scripts/codegen/requestMetadataCollector.d.ts.map +1 -0
- package/dist/scripts/codegen/requestMetadataCollector.js +48 -0
- package/dist/scripts/codegen/requestMetadataCollector.js.map +1 -0
- package/dist/scripts/codegen/types.d.ts +77 -0
- package/dist/scripts/codegen/types.d.ts.map +1 -0
- package/dist/scripts/codegen/types.js +10 -0
- package/dist/scripts/codegen/types.js.map +1 -0
- package/dist/scripts/codegen.d.ts +24 -0
- package/dist/scripts/codegen.d.ts.map +1 -0
- package/dist/scripts/codegen.js +95 -0
- package/dist/scripts/codegen.js.map +1 -0
- package/dist/scripts/cryptFile.js +7 -2
- package/dist/scripts/cryptFile.js.map +1 -1
- package/dist/src/apiCredentialStore.d.ts +1 -1
- package/dist/src/apiCredentialStore.d.ts.map +1 -1
- package/dist/src/apiCredentialStore.js +1 -1
- package/dist/src/apiCredentialStore.js.map +1 -1
- package/dist/src/apiCredentials.d.ts +11 -114
- package/dist/src/apiCredentials.d.ts.map +1 -1
- package/dist/src/apiCredentials.js +9 -101
- package/dist/src/apiCredentials.js.map +1 -1
- package/dist/src/apiCredentialsSerialization.d.ts +119 -0
- package/dist/src/apiCredentialsSerialization.d.ts.map +1 -0
- package/dist/src/apiCredentialsSerialization.js +90 -0
- package/dist/src/apiCredentialsSerialization.js.map +1 -0
- package/dist/src/browserConfig.d.ts +1 -5
- package/dist/src/browserConfig.d.ts.map +1 -1
- package/dist/src/browserConfig.js +2 -8
- package/dist/src/browserConfig.js.map +1 -1
- package/dist/src/cli.js +20 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/cliCommands.d.ts +0 -1
- package/dist/src/cliCommands.d.ts.map +1 -1
- package/dist/src/cliCommands.js +50 -40
- package/dist/src/cliCommands.js.map +1 -1
- package/dist/src/config.d.ts +4 -3
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +17 -29
- package/dist/src/config.js.map +1 -1
- package/dist/src/curl.d.ts +10 -0
- package/dist/src/curl.d.ts.map +1 -1
- package/dist/src/curl.js +88 -0
- package/dist/src/curl.js.map +1 -1
- package/dist/src/encryptedStorage.d.ts +10 -2
- package/dist/src/encryptedStorage.d.ts.map +1 -1
- package/dist/src/encryptedStorage.js +30 -38
- package/dist/src/encryptedStorage.js.map +1 -1
- package/dist/src/index.d.ts +5 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/keychain.d.ts +0 -4
- package/dist/src/keychain.d.ts.map +1 -1
- package/dist/src/keychain.js +0 -13
- package/dist/src/keychain.js.map +1 -1
- package/dist/src/migrations.d.ts +9 -0
- package/dist/src/migrations.d.ts.map +1 -0
- package/dist/src/migrations.js +77 -0
- package/dist/src/migrations.js.map +1 -0
- package/dist/src/oauthUtils.d.ts +4 -1
- package/dist/src/oauthUtils.d.ts.map +1 -1
- package/dist/src/oauthUtils.js.map +1 -1
- package/dist/src/playwrightUtils.d.ts +2 -2
- package/dist/src/playwrightUtils.d.ts.map +1 -1
- package/dist/src/playwrightUtils.js +4 -4
- package/dist/src/playwrightUtils.js.map +1 -1
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +18 -2
- package/dist/src/registry.js.map +1 -1
- package/dist/src/services/aws.d.ts +44 -0
- package/dist/src/services/aws.d.ts.map +1 -0
- package/dist/src/services/aws.js +237 -0
- package/dist/src/services/aws.js.map +1 -0
- package/dist/src/services/base.d.ts +14 -0
- package/dist/src/services/base.d.ts.map +1 -1
- package/dist/src/services/base.js +23 -11
- package/dist/src/services/base.js.map +1 -1
- package/dist/src/services/calendly.d.ts +12 -0
- package/dist/src/services/calendly.d.ts.map +1 -0
- package/dist/src/services/calendly.js +18 -0
- package/dist/src/services/calendly.js.map +1 -0
- package/dist/src/services/discord.d.ts +1 -0
- package/dist/src/services/discord.d.ts.map +1 -1
- package/dist/src/services/discord.js +3 -0
- package/dist/src/services/discord.js.map +1 -1
- package/dist/src/services/dropbox.d.ts +2 -1
- package/dist/src/services/dropbox.d.ts.map +1 -1
- package/dist/src/services/dropbox.js +5 -0
- package/dist/src/services/dropbox.js.map +1 -1
- package/dist/src/services/figma.d.ts +12 -0
- package/dist/src/services/figma.d.ts.map +1 -0
- package/dist/src/services/figma.js +14 -0
- package/dist/src/services/figma.js.map +1 -0
- package/dist/src/services/github.d.ts +1 -0
- package/dist/src/services/github.d.ts.map +1 -1
- package/dist/src/services/github.js +3 -0
- package/dist/src/services/github.js.map +1 -1
- package/dist/src/services/gitlab.d.ts +12 -0
- package/dist/src/services/gitlab.d.ts.map +1 -0
- package/dist/src/services/gitlab.js +14 -0
- package/dist/src/services/gitlab.js.map +1 -0
- package/dist/src/services/google/analytics.d.ts +11 -0
- package/dist/src/services/google/analytics.d.ts.map +1 -0
- package/dist/src/services/google/analytics.js +22 -0
- package/dist/src/services/google/analytics.js.map +1 -0
- package/dist/src/services/google/base.d.ts +73 -0
- package/dist/src/services/google/base.d.ts.map +1 -0
- package/dist/src/services/google/base.js +323 -0
- package/dist/src/services/google/base.js.map +1 -0
- package/dist/src/services/google/calendar.d.ts +11 -0
- package/dist/src/services/google/calendar.d.ts.map +1 -0
- package/dist/src/services/google/calendar.js +22 -0
- package/dist/src/services/google/calendar.js.map +1 -0
- package/dist/src/services/google/directions.d.ts +14 -0
- package/dist/src/services/google/directions.d.ts.map +1 -0
- package/dist/src/services/google/directions.js +49 -0
- package/dist/src/services/google/directions.js.map +1 -0
- package/dist/src/services/google/docs.d.ts +11 -0
- package/dist/src/services/google/docs.d.ts.map +1 -0
- package/dist/src/services/google/docs.js +19 -0
- package/dist/src/services/google/docs.js.map +1 -0
- package/dist/src/services/google/drive.d.ts +11 -0
- package/dist/src/services/google/drive.d.ts.map +1 -0
- package/dist/src/services/google/drive.js +19 -0
- package/dist/src/services/google/drive.js.map +1 -0
- package/dist/src/services/google/gmail.d.ts +11 -0
- package/dist/src/services/google/gmail.d.ts.map +1 -0
- package/dist/src/services/google/gmail.js +24 -0
- package/dist/src/services/google/gmail.js.map +1 -0
- package/dist/src/services/google/maps.d.ts +39 -0
- package/dist/src/services/google/maps.d.ts.map +1 -0
- package/dist/src/services/google/maps.js +94 -0
- package/dist/src/services/google/maps.js.map +1 -0
- package/dist/src/services/google/people.d.ts +11 -0
- package/dist/src/services/google/people.d.ts.map +1 -0
- package/dist/src/services/google/people.js +22 -0
- package/dist/src/services/google/people.js.map +1 -0
- package/dist/src/services/google/sheets.d.ts +11 -0
- package/dist/src/services/google/sheets.d.ts.map +1 -0
- package/dist/src/services/google/sheets.js +19 -0
- package/dist/src/services/google/sheets.js.map +1 -0
- package/dist/src/services/googleAnalytics.d.ts +11 -0
- package/dist/src/services/googleAnalytics.d.ts.map +1 -0
- package/dist/src/services/googleAnalytics.js +18 -0
- package/dist/src/services/googleAnalytics.js.map +1 -0
- package/dist/src/services/googleMaps.d.ts +12 -0
- package/dist/src/services/googleMaps.d.ts.map +1 -0
- package/dist/src/services/googleMaps.js +17 -0
- package/dist/src/services/googleMaps.js.map +1 -0
- package/dist/src/services/index.d.ts +19 -2
- package/dist/src/services/index.d.ts.map +1 -1
- package/dist/src/services/index.js +19 -2
- package/dist/src/services/index.js.map +1 -1
- package/dist/src/services/linear.d.ts +1 -0
- package/dist/src/services/linear.d.ts.map +1 -1
- package/dist/src/services/linear.js +3 -0
- package/dist/src/services/linear.js.map +1 -1
- package/dist/src/services/mailchimp.d.ts +2 -1
- package/dist/src/services/mailchimp.d.ts.map +1 -1
- package/dist/src/services/mailchimp.js +4 -3
- package/dist/src/services/mailchimp.js.map +1 -1
- package/dist/src/services/notion.d.ts +1 -0
- package/dist/src/services/notion.d.ts.map +1 -1
- package/dist/src/services/notion.js +3 -0
- package/dist/src/services/notion.js.map +1 -1
- package/dist/src/services/sentry.d.ts +14 -0
- package/dist/src/services/sentry.d.ts.map +1 -0
- package/dist/src/services/sentry.js +43 -0
- package/dist/src/services/sentry.js.map +1 -0
- package/dist/src/services/slack.d.ts +30 -1
- package/dist/src/services/slack.d.ts.map +1 -1
- package/dist/src/services/slack.js +45 -2
- package/dist/src/services/slack.js.map +1 -1
- package/dist/src/services/stripe.d.ts +12 -0
- package/dist/src/services/stripe.d.ts.map +1 -0
- package/dist/src/services/stripe.js +14 -0
- package/dist/src/services/stripe.js.map +1 -0
- package/dist/src/services/telegram.d.ts +40 -0
- package/dist/src/services/telegram.d.ts.map +1 -0
- package/dist/src/services/telegram.js +73 -0
- package/dist/src/services/telegram.js.map +1 -0
- package/dist/src/services/yelp.d.ts +12 -0
- package/dist/src/services/yelp.d.ts.map +1 -0
- package/dist/src/services/yelp.js +16 -0
- package/dist/src/services/yelp.js.map +1 -0
- package/dist/src/services/zoom.d.ts +12 -0
- package/dist/src/services/zoom.d.ts.map +1 -0
- package/dist/src/services/zoom.js +18 -0
- package/dist/src/services/zoom.js.map +1 -0
- package/dist/tests/apiCredentialStore.test.js +2 -19
- package/dist/tests/apiCredentialStore.test.js.map +1 -1
- package/dist/tests/apiCredentials.test.js +139 -178
- package/dist/tests/apiCredentials.test.js.map +1 -1
- package/dist/tests/cli.test.js +160 -260
- package/dist/tests/cli.test.js.map +1 -1
- package/dist/tests/encryptedStorage.test.js +0 -4
- package/dist/tests/encryptedStorage.test.js.map +1 -1
- package/dist/tests/encryptedStorageKeyGeneration.test.d.ts +2 -0
- package/dist/tests/encryptedStorageKeyGeneration.test.d.ts.map +1 -0
- package/dist/tests/encryptedStorageKeyGeneration.test.js +22 -0
- package/dist/tests/encryptedStorageKeyGeneration.test.js.map +1 -0
- package/dist/tests/encryption.test.js +3 -35
- package/dist/tests/encryption.test.js.map +1 -1
- package/dist/tests/migrations.test.d.ts +2 -0
- package/dist/tests/migrations.test.d.ts.map +1 -0
- package/dist/tests/migrations.test.js +164 -0
- package/dist/tests/migrations.test.js.map +1 -0
- package/dist/tests/playwrightDownload.test.js +2 -65
- package/dist/tests/playwrightDownload.test.js.map +1 -1
- package/dist/tests/registry.test.js +49 -75
- package/dist/tests/registry.test.js.map +1 -1
- package/dist/tests/servicesAgainstRecordings.test.js +1 -1
- package/dist/tests/servicesAgainstRecordings.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Service } from './base.js';
|
|
2
|
+
export class Gitlab extends Service {
|
|
3
|
+
name = 'gitlab';
|
|
4
|
+
displayName = 'GitLab';
|
|
5
|
+
baseApiUrls = ['https://gitlab.com/api/'];
|
|
6
|
+
loginUrl = 'https://gitlab.com/users/sign_in';
|
|
7
|
+
info = 'https://docs.gitlab.com/api/rest/.';
|
|
8
|
+
credentialCheckCurlArguments = ['https://gitlab.com/api/v4/user'];
|
|
9
|
+
setCredentialsExample(serviceName) {
|
|
10
|
+
return `latchkey auth set ${serviceName} -H "PRIVATE-TOKEN: <token>"`;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export const GITLAB = new Gitlab();
|
|
14
|
+
//# sourceMappingURL=gitlab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitlab.js","sourceRoot":"","sources":["../../../src/services/gitlab.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,OAAO,MAAO,SAAQ,OAAO;IACxB,IAAI,GAAG,QAAQ,CAAC;IAChB,WAAW,GAAG,QAAQ,CAAC;IACvB,WAAW,GAAG,CAAC,yBAAyB,CAAU,CAAC;IACnD,QAAQ,GAAG,kCAAkC,CAAC;IAC9C,IAAI,GAAG,oCAAoC,CAAC;IAE5C,4BAA4B,GAAG,CAAC,gCAAgC,CAAU,CAAC;IAEpF,qBAAqB,CAAC,WAAmB;QACvC,OAAO,qBAAqB,WAAW,8BAA8B,CAAC;IACxE,CAAC;CACF;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { GoogleService, type GoogleServiceConfig } from './base.js';
|
|
2
|
+
export declare class GoogleAnalytics extends GoogleService {
|
|
3
|
+
readonly name = "google-analytics";
|
|
4
|
+
readonly displayName = "Google Analytics";
|
|
5
|
+
readonly baseApiUrls: readonly ["https://analyticsdata.googleapis.com/", "https://analyticsadmin.googleapis.com/"];
|
|
6
|
+
readonly info: string;
|
|
7
|
+
readonly credentialCheckCurlArguments: readonly ["https://analyticsadmin.googleapis.com/v1beta/accountSummaries"];
|
|
8
|
+
protected readonly config: GoogleServiceConfig;
|
|
9
|
+
}
|
|
10
|
+
export declare const GOOGLE_ANALYTICS: GoogleAnalytics;
|
|
11
|
+
//# sourceMappingURL=analytics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../../../src/services/google/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAOpE,qBAAa,eAAgB,SAAQ,aAAa;IAChD,QAAQ,CAAC,IAAI,sBAAsB;IACnC,QAAQ,CAAC,WAAW,sBAAsB;IAC1C,QAAQ,CAAC,WAAW,+FAGT;IACX,QAAQ,CAAC,IAAI,SAG0D;IAEvE,QAAQ,CAAC,4BAA4B,6EAE1B;IAEX,SAAS,CAAC,QAAQ,CAAC,MAAM,sBAAU;CACpC;AAED,eAAO,MAAM,gBAAgB,iBAAwB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { GoogleService } from './base.js';
|
|
2
|
+
const CONFIG = {
|
|
3
|
+
api: 'analyticsdata.googleapis.com',
|
|
4
|
+
scopes: ['https://www.googleapis.com/auth/analytics.readonly'],
|
|
5
|
+
};
|
|
6
|
+
export class GoogleAnalytics extends GoogleService {
|
|
7
|
+
name = 'google-analytics';
|
|
8
|
+
displayName = 'Google Analytics';
|
|
9
|
+
baseApiUrls = [
|
|
10
|
+
'https://analyticsdata.googleapis.com/',
|
|
11
|
+
'https://analyticsadmin.googleapis.com/',
|
|
12
|
+
];
|
|
13
|
+
info = 'https://developers.google.com/analytics/devguides/reporting/data/v1. ' +
|
|
14
|
+
'If needed, run "latchkey auth browser-prepare google-analytics" to create an OAuth client first. ' +
|
|
15
|
+
'It may take a few minutes before the OAuth client is ready to use.';
|
|
16
|
+
credentialCheckCurlArguments = [
|
|
17
|
+
'https://analyticsadmin.googleapis.com/v1beta/accountSummaries',
|
|
18
|
+
];
|
|
19
|
+
config = CONFIG;
|
|
20
|
+
}
|
|
21
|
+
export const GOOGLE_ANALYTICS = new GoogleAnalytics();
|
|
22
|
+
//# sourceMappingURL=analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../../../src/services/google/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA4B,MAAM,WAAW,CAAC;AAEpE,MAAM,MAAM,GAAwB;IAClC,GAAG,EAAE,8BAA8B;IACnC,MAAM,EAAE,CAAC,oDAAoD,CAAC;CAC/D,CAAC;AAEF,MAAM,OAAO,eAAgB,SAAQ,aAAa;IACvC,IAAI,GAAG,kBAAkB,CAAC;IAC1B,WAAW,GAAG,kBAAkB,CAAC;IACjC,WAAW,GAAG;QACrB,uCAAuC;QACvC,wCAAwC;KAChC,CAAC;IACF,IAAI,GACX,uEAAuE;QACvE,mGAAmG;QACnG,oEAAoE,CAAC;IAE9D,4BAA4B,GAAG;QACtC,+DAA+D;KACvD,CAAC;IAEQ,MAAM,GAAG,MAAM,CAAC;CACpC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared base class and helpers for Google OAuth services.
|
|
3
|
+
*
|
|
4
|
+
* Each concrete Google service (Gmail, Drive, etc.) extends GoogleService
|
|
5
|
+
* and provides its own API, scopes, and credential check endpoint.
|
|
6
|
+
* The OAuth / browser-prepare flow is self-contained per service.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import type { Browser, BrowserContext, Response } from 'playwright';
|
|
10
|
+
import { type ApiCredentials } from '../../apiCredentials.js';
|
|
11
|
+
import { type BrowserLaunchOptions } from '../../playwrightUtils.js';
|
|
12
|
+
import { Service, BrowserFollowupServiceSession } from '../base.js';
|
|
13
|
+
import type { EncryptedStorage } from '../../encryptedStorage.js';
|
|
14
|
+
/**
|
|
15
|
+
* Google API key credentials.
|
|
16
|
+
* The API key is injected as an `X-Goog-Api-Key` header.
|
|
17
|
+
*/
|
|
18
|
+
export declare const GoogleApiKeyCredentialsSchema: z.ZodObject<{
|
|
19
|
+
objectType: z.ZodLiteral<"googleApiKey">;
|
|
20
|
+
apiKey: z.ZodString;
|
|
21
|
+
}, "strip", z.ZodTypeAny, {
|
|
22
|
+
objectType: "googleApiKey";
|
|
23
|
+
apiKey: string;
|
|
24
|
+
}, {
|
|
25
|
+
objectType: "googleApiKey";
|
|
26
|
+
apiKey: string;
|
|
27
|
+
}>;
|
|
28
|
+
export type GoogleApiKeyCredentialsData = z.infer<typeof GoogleApiKeyCredentialsSchema>;
|
|
29
|
+
export declare class GoogleApiKeyCredentials implements ApiCredentials {
|
|
30
|
+
readonly objectType: "googleApiKey";
|
|
31
|
+
readonly apiKey: string;
|
|
32
|
+
constructor(apiKey: string);
|
|
33
|
+
injectIntoCurlCall(curlArguments: readonly string[]): readonly string[];
|
|
34
|
+
isExpired(): boolean | undefined;
|
|
35
|
+
toJSON(): GoogleApiKeyCredentialsData;
|
|
36
|
+
static fromJSON(data: GoogleApiKeyCredentialsData): GoogleApiKeyCredentials;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Configuration for a specific Google API service.
|
|
40
|
+
*/
|
|
41
|
+
export interface GoogleServiceConfig {
|
|
42
|
+
/** The Google API identifier (e.g., 'gmail.googleapis.com'). */
|
|
43
|
+
readonly api: string;
|
|
44
|
+
/** OAuth scopes required by this service. */
|
|
45
|
+
readonly scopes: readonly string[];
|
|
46
|
+
}
|
|
47
|
+
declare class GoogleServiceSession extends BrowserFollowupServiceSession {
|
|
48
|
+
private readonly loginDetector;
|
|
49
|
+
private readonly config;
|
|
50
|
+
constructor(service: GoogleService, config: GoogleServiceConfig);
|
|
51
|
+
onResponse(response: Response): void;
|
|
52
|
+
protected isLoginComplete(): boolean;
|
|
53
|
+
protected finalizeCredentials(_browser: Browser, context: BrowserContext, oldCredentials?: ApiCredentials): Promise<ApiCredentials | null>;
|
|
54
|
+
protected performBrowserFollowup(context: BrowserContext, oldCredentials?: ApiCredentials): Promise<ApiCredentials | null>;
|
|
55
|
+
prepare(encryptedStorage: EncryptedStorage, launchOptions?: BrowserLaunchOptions): Promise<ApiCredentials>;
|
|
56
|
+
private performOAuthFlow;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Abstract base class for individual Google API services.
|
|
60
|
+
*
|
|
61
|
+
* Each subclass declares the specific API, scopes, and credential-check endpoint
|
|
62
|
+
* it needs. The OAuth and browser-prepare flows are handled here and scoped
|
|
63
|
+
* to that single API.
|
|
64
|
+
*/
|
|
65
|
+
export declare abstract class GoogleService extends Service {
|
|
66
|
+
readonly loginUrl = "https://console.cloud.google.com/";
|
|
67
|
+
protected abstract readonly config: GoogleServiceConfig;
|
|
68
|
+
setCredentialsExample(serviceName: string): string;
|
|
69
|
+
getSession(): GoogleServiceSession;
|
|
70
|
+
refreshCredentials(apiCredentials: ApiCredentials): Promise<ApiCredentials | null>;
|
|
71
|
+
}
|
|
72
|
+
export {};
|
|
73
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/services/google/base.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAQ,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,KAAK,cAAc,EAAoB,MAAM,yBAAyB,CAAC;AAEhF,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,0BAA0B,CAAC;AAMlC,OAAO,EACL,OAAO,EACP,6BAA6B,EAI9B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,6BAA6B;;;;;;;;;EAGxC,CAAC;AAEH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAExF,qBAAa,uBAAwB,YAAW,cAAc;IAC5D,QAAQ,CAAC,UAAU,EAAG,cAAc,CAAU;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE,MAAM;IAI1B,kBAAkB,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE;IAQvE,SAAS,IAAI,OAAO,GAAG,SAAS;IAIhC,MAAM,IAAI,2BAA2B;IAOrC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,2BAA2B,GAAG,uBAAuB;CAG5E;AA6ND;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,cAAM,oBAAqB,SAAQ,6BAA6B;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;gBAEjC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,mBAAmB;IAK/D,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAIpC,SAAS,CAAC,eAAe,IAAI,OAAO;cAIjB,mBAAmB,CACpC,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,cAAc,EACvB,cAAc,CAAC,EAAE,cAAc,GAC9B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;cAIjB,sBAAsB,CACpC,OAAO,EAAE,cAAc,EACvB,cAAc,CAAC,EAAE,cAAc,GAC9B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IA8BlB,OAAO,CACpB,gBAAgB,EAAE,gBAAgB,EAClC,aAAa,CAAC,EAAE,oBAAoB,GACnC,OAAO,CAAC,cAAc,CAAC;YAsBZ,gBAAgB;CA8D/B;AAED;;;;;;GAMG;AACH,8BAAsB,aAAc,SAAQ,OAAO;IACjD,QAAQ,CAAC,QAAQ,uCAAuC;IAExD,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IAExD,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAIzC,UAAU,IAAI,oBAAoB;IAIlC,kBAAkB,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAiC5F"}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared base class and helpers for Google OAuth services.
|
|
3
|
+
*
|
|
4
|
+
* Each concrete Google service (Gmail, Drive, etc.) extends GoogleService
|
|
5
|
+
* and provides its own API, scopes, and credential check endpoint.
|
|
6
|
+
* The OAuth / browser-prepare flow is self-contained per service.
|
|
7
|
+
*/
|
|
8
|
+
import fs from 'node:fs/promises';
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
import { OAuthCredentials } from '../../apiCredentials.js';
|
|
11
|
+
import { extractUrlFromCurlArguments } from '../../curl.js';
|
|
12
|
+
import { generateLatchkeyAppName, showSpinnerPage, withTempBrowserContext, } from '../../playwrightUtils.js';
|
|
13
|
+
import { exchangeCodeForTokens, refreshAccessToken, startOAuthCallbackServer, } from '../../oauthUtils.js';
|
|
14
|
+
import { Service, BrowserFollowupServiceSession, LoginFailedError, LoginCancelledError, isBrowserClosedError, } from '../base.js';
|
|
15
|
+
/**
|
|
16
|
+
* Google API key credentials.
|
|
17
|
+
* The API key is injected as an `X-Goog-Api-Key` header.
|
|
18
|
+
*/
|
|
19
|
+
export const GoogleApiKeyCredentialsSchema = z.object({
|
|
20
|
+
objectType: z.literal('googleApiKey'),
|
|
21
|
+
apiKey: z.string(),
|
|
22
|
+
});
|
|
23
|
+
export class GoogleApiKeyCredentials {
|
|
24
|
+
objectType = 'googleApiKey';
|
|
25
|
+
apiKey;
|
|
26
|
+
constructor(apiKey) {
|
|
27
|
+
this.apiKey = apiKey;
|
|
28
|
+
}
|
|
29
|
+
injectIntoCurlCall(curlArguments) {
|
|
30
|
+
const url = extractUrlFromCurlArguments(curlArguments);
|
|
31
|
+
if (!url?.startsWith('https://') || !url.includes('.googleapis.com')) {
|
|
32
|
+
return curlArguments;
|
|
33
|
+
}
|
|
34
|
+
return ['-H', `X-Goog-Api-Key: ${this.apiKey}`, ...curlArguments];
|
|
35
|
+
}
|
|
36
|
+
isExpired() {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
toJSON() {
|
|
40
|
+
return {
|
|
41
|
+
objectType: this.objectType,
|
|
42
|
+
apiKey: this.apiKey,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
static fromJSON(data) {
|
|
46
|
+
return new GoogleApiKeyCredentials(data.apiKey);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const DEFAULT_TIMEOUT_MS = 8000;
|
|
50
|
+
const LOGIN_TIMEOUT_MS = 120000;
|
|
51
|
+
const GOOGLE_TOKEN_ENDPOINT = 'https://oauth2.googleapis.com/token';
|
|
52
|
+
/** Scopes always requested alongside service-specific scopes (for credential validation). */
|
|
53
|
+
const COMMON_SCOPES = [
|
|
54
|
+
'https://www.googleapis.com/auth/userinfo.profile',
|
|
55
|
+
'https://www.googleapis.com/auth/userinfo.email',
|
|
56
|
+
];
|
|
57
|
+
function parseClientSecretJson(content) {
|
|
58
|
+
try {
|
|
59
|
+
const json = JSON.parse(content);
|
|
60
|
+
const config = json.installed ?? json.web;
|
|
61
|
+
if (!config) {
|
|
62
|
+
throw new LoginFailedError('Invalid client_secret.json: missing "installed" or "web" configuration.');
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
clientId: config.client_id,
|
|
66
|
+
clientSecret: config.client_secret,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (error instanceof LoginFailedError) {
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
throw new LoginFailedError(`Failed to parse client_secret.json: ${error instanceof Error ? error.message : String(error)}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function createProject(page, appName) {
|
|
77
|
+
await page.goto('https://console.cloud.google.com/projectselector2/home/dashboard', {
|
|
78
|
+
timeout: DEFAULT_TIMEOUT_MS,
|
|
79
|
+
});
|
|
80
|
+
const createProjectButton = page.locator('.projectselector-project-create');
|
|
81
|
+
await createProjectButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
82
|
+
await createProjectButton.click();
|
|
83
|
+
const projectNameInput = page.locator('proj-name-id-input input');
|
|
84
|
+
await projectNameInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS * 100 });
|
|
85
|
+
await projectNameInput.fill(appName);
|
|
86
|
+
const createButton = page.locator('button[type="submit"]');
|
|
87
|
+
await createButton.click();
|
|
88
|
+
await page.waitForURL('https://console.cloud.google.com/home/dashboard?project=**', {
|
|
89
|
+
timeout: 16000,
|
|
90
|
+
});
|
|
91
|
+
const urlObj = new URL(page.url());
|
|
92
|
+
const projectId = urlObj.searchParams.get('project');
|
|
93
|
+
if (!projectId) {
|
|
94
|
+
throw new LoginFailedError('Failed to create or retrieve Google Cloud project ID.');
|
|
95
|
+
}
|
|
96
|
+
return projectId;
|
|
97
|
+
}
|
|
98
|
+
async function enableApi(page, projectSlug, apiName) {
|
|
99
|
+
await page.goto(`https://console.cloud.google.com/apis/library/${apiName}?project=${projectSlug}`, {
|
|
100
|
+
timeout: DEFAULT_TIMEOUT_MS,
|
|
101
|
+
});
|
|
102
|
+
const successIcon = page.locator('.cfc-icon-status-success');
|
|
103
|
+
const enableButton = page
|
|
104
|
+
.locator('.mp-details-cta-button-primary button .mdc-button__label')
|
|
105
|
+
.filter({ visible: true });
|
|
106
|
+
const sucessOrEnableButton = successIcon.or(enableButton);
|
|
107
|
+
await sucessOrEnableButton.isVisible({ timeout: DEFAULT_TIMEOUT_MS });
|
|
108
|
+
if (await successIcon.isVisible()) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
await enableButton.click();
|
|
112
|
+
const stopIndicator = page.locator('.cfc-icon-stop');
|
|
113
|
+
await stopIndicator.waitFor({ timeout: 18000 });
|
|
114
|
+
}
|
|
115
|
+
async function configureBranding(page, projectSlug, appName) {
|
|
116
|
+
await page.goto(`https://console.cloud.google.com/auth/branding?project=${projectSlug}`, {
|
|
117
|
+
timeout: DEFAULT_TIMEOUT_MS,
|
|
118
|
+
});
|
|
119
|
+
const getStartedButton = page.locator('cfc-empty-state-actions .mdc-button__label');
|
|
120
|
+
await getStartedButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
121
|
+
await getStartedButton.click();
|
|
122
|
+
const appNameInput = page.locator('input[formcontrolname="displayName"]');
|
|
123
|
+
await appNameInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
124
|
+
await appNameInput.fill(appName);
|
|
125
|
+
const emailSelector = page.locator('svg[data-icon-name="arrowDropDownIcon"]').nth(0);
|
|
126
|
+
await emailSelector.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
127
|
+
await emailSelector.click();
|
|
128
|
+
const supportEmailOption = page.locator('mat-option > span:nth-child(1)').first();
|
|
129
|
+
await supportEmailOption.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
130
|
+
const supportEmailValue = await supportEmailOption.textContent();
|
|
131
|
+
await supportEmailOption.click();
|
|
132
|
+
const nextButton = page.locator('.cfc-stepper-step-button');
|
|
133
|
+
await nextButton.click();
|
|
134
|
+
const internalAudienceRadio = page.locator('.mdc-radio').nth(0);
|
|
135
|
+
await internalAudienceRadio.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
136
|
+
await internalAudienceRadio.click();
|
|
137
|
+
await nextButton.click();
|
|
138
|
+
const contactEmailInput = page.locator('mat-chip-grid[formcontrolname="emails"] input');
|
|
139
|
+
await contactEmailInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
140
|
+
await contactEmailInput.fill(supportEmailValue ?? '');
|
|
141
|
+
await nextButton.click();
|
|
142
|
+
const agreeCheckbox = page.locator('input[type="checkbox"]');
|
|
143
|
+
await agreeCheckbox.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
144
|
+
await agreeCheckbox.click();
|
|
145
|
+
await nextButton.click();
|
|
146
|
+
const createButton = page.locator('.cfc-stepper-submit-button button');
|
|
147
|
+
await createButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
148
|
+
await createButton.click();
|
|
149
|
+
}
|
|
150
|
+
async function createOAuthClient(page, appName) {
|
|
151
|
+
await page.goto('https://console.cloud.google.com/apis/credentials', {
|
|
152
|
+
timeout: DEFAULT_TIMEOUT_MS,
|
|
153
|
+
});
|
|
154
|
+
const createCredentialsButton = page.locator('services-create-credentials-menu button');
|
|
155
|
+
await createCredentialsButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
156
|
+
await createCredentialsButton.click();
|
|
157
|
+
const oauthClientIdOption = page.locator('cfc-menu-item[track-metadata-type="OAUTH_CLIENT"]');
|
|
158
|
+
await oauthClientIdOption.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
159
|
+
await oauthClientIdOption.click();
|
|
160
|
+
const applicationTypeDropdown = page.locator('svg[data-icon-name="arrowDropDownIcon"]').nth(0);
|
|
161
|
+
await applicationTypeDropdown.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
162
|
+
await applicationTypeDropdown.click();
|
|
163
|
+
const desktopAppOption = page.locator('#_1rif_mat-option-5');
|
|
164
|
+
await desktopAppOption.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
165
|
+
await desktopAppOption.click();
|
|
166
|
+
const clientNameInput = page.locator('input[formcontrolname="displayName"]');
|
|
167
|
+
await clientNameInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
168
|
+
await clientNameInput.fill(appName);
|
|
169
|
+
const createButton = page.locator('cfc-progress-button button');
|
|
170
|
+
await createButton.click();
|
|
171
|
+
const downloadButton = page.locator('cfc-icon[icon="download"]');
|
|
172
|
+
await downloadButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
173
|
+
const [download] = await Promise.all([page.waitForEvent('download'), downloadButton.click()]);
|
|
174
|
+
const path = await download.path();
|
|
175
|
+
if (!path) {
|
|
176
|
+
throw new LoginFailedError('Failed to download client_secret.json');
|
|
177
|
+
}
|
|
178
|
+
const content = await fs.readFile(path, 'utf-8');
|
|
179
|
+
return parseClientSecretJson(content);
|
|
180
|
+
}
|
|
181
|
+
function checkGoogleLoginResponse(response, loginDetector) {
|
|
182
|
+
if (loginDetector.isLoggedIn) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const request = response.request();
|
|
186
|
+
if (request.url().startsWith('https://console.cloud.google.com/')) {
|
|
187
|
+
if (response.status() === 200) {
|
|
188
|
+
void response.text().then((text) => {
|
|
189
|
+
if (!text.includes('accounts.google.com/signin')) {
|
|
190
|
+
loginDetector.isLoggedIn = true;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async function waitForGoogleLogin(page) {
|
|
197
|
+
const loginDetector = { isLoggedIn: false };
|
|
198
|
+
const responseHandler = (response) => {
|
|
199
|
+
checkGoogleLoginResponse(response, loginDetector);
|
|
200
|
+
};
|
|
201
|
+
page.on('response', responseHandler);
|
|
202
|
+
while (!loginDetector.isLoggedIn) {
|
|
203
|
+
await page.waitForTimeout(100);
|
|
204
|
+
}
|
|
205
|
+
page.off('response', responseHandler);
|
|
206
|
+
}
|
|
207
|
+
class GoogleServiceSession extends BrowserFollowupServiceSession {
|
|
208
|
+
loginDetector = { isLoggedIn: false };
|
|
209
|
+
config;
|
|
210
|
+
constructor(service, config) {
|
|
211
|
+
super(service);
|
|
212
|
+
this.config = config;
|
|
213
|
+
}
|
|
214
|
+
onResponse(response) {
|
|
215
|
+
checkGoogleLoginResponse(response, this.loginDetector);
|
|
216
|
+
}
|
|
217
|
+
isLoginComplete() {
|
|
218
|
+
return this.loginDetector.isLoggedIn;
|
|
219
|
+
}
|
|
220
|
+
finalizeCredentials(_browser, context, oldCredentials) {
|
|
221
|
+
return this.performBrowserFollowup(context, oldCredentials);
|
|
222
|
+
}
|
|
223
|
+
async performBrowserFollowup(context, oldCredentials) {
|
|
224
|
+
const page = context.pages()[0];
|
|
225
|
+
if (!page) {
|
|
226
|
+
throw new LoginFailedError('No page available in browser context.');
|
|
227
|
+
}
|
|
228
|
+
if (!(oldCredentials instanceof OAuthCredentials)) {
|
|
229
|
+
throw new LoginFailedError(`${this.service.displayName} login requires existing OAuth client credentials. Run browser-prepare first.`);
|
|
230
|
+
}
|
|
231
|
+
const clientId = oldCredentials.clientId;
|
|
232
|
+
const clientSecret = oldCredentials.clientSecret;
|
|
233
|
+
const { accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt } = await this.performOAuthFlow(context, page, clientId, clientSecret);
|
|
234
|
+
await page.close();
|
|
235
|
+
return new OAuthCredentials(clientId, clientSecret, accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt);
|
|
236
|
+
}
|
|
237
|
+
async prepare(encryptedStorage, launchOptions) {
|
|
238
|
+
return withTempBrowserContext(encryptedStorage, launchOptions ?? {}, async ({ context }) => {
|
|
239
|
+
const page = await context.newPage();
|
|
240
|
+
await page.goto(this.service.loginUrl);
|
|
241
|
+
await waitForGoogleLogin(page);
|
|
242
|
+
const serviceSuffix = this.service.name.replace(/^google/, '');
|
|
243
|
+
const appName = generateLatchkeyAppName(serviceSuffix);
|
|
244
|
+
await showSpinnerPage(context, `Finalizing ${this.service.displayName} login...\nThis can take a few minutes.`);
|
|
245
|
+
const projectSlug = await createProject(page, appName);
|
|
246
|
+
await enableApi(page, projectSlug, this.config.api);
|
|
247
|
+
await configureBranding(page, projectSlug, appName);
|
|
248
|
+
const { clientId, clientSecret } = await createOAuthClient(page, appName);
|
|
249
|
+
await page.close();
|
|
250
|
+
return new OAuthCredentials(clientId, clientSecret);
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
async performOAuthFlow(context, page, clientId, clientSecret) {
|
|
254
|
+
const abortController = new AbortController();
|
|
255
|
+
const closeHandler = () => {
|
|
256
|
+
abortController.abort();
|
|
257
|
+
};
|
|
258
|
+
page.on('close', closeHandler);
|
|
259
|
+
context.on('close', closeHandler);
|
|
260
|
+
const allScopes = [...COMMON_SCOPES, ...this.config.scopes];
|
|
261
|
+
try {
|
|
262
|
+
const { port, codePromise } = await startOAuthCallbackServer(LOGIN_TIMEOUT_MS, abortController.signal);
|
|
263
|
+
const redirectUri = `http://localhost:${port.toString()}/oauth2callback`;
|
|
264
|
+
const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth');
|
|
265
|
+
authUrl.searchParams.set('client_id', clientId);
|
|
266
|
+
authUrl.searchParams.set('redirect_uri', redirectUri);
|
|
267
|
+
authUrl.searchParams.set('response_type', 'code');
|
|
268
|
+
authUrl.searchParams.set('scope', allScopes.join(' '));
|
|
269
|
+
authUrl.searchParams.set('access_type', 'offline');
|
|
270
|
+
authUrl.searchParams.set('prompt', 'consent');
|
|
271
|
+
await page.goto(authUrl.toString());
|
|
272
|
+
const code = await codePromise;
|
|
273
|
+
const tokens = exchangeCodeForTokens(GOOGLE_TOKEN_ENDPOINT, code, clientId, clientSecret, redirectUri);
|
|
274
|
+
const accessTokenExpiresAt = new Date(Date.now() + tokens.expires_in * 1000).toISOString();
|
|
275
|
+
return {
|
|
276
|
+
accessToken: tokens.access_token,
|
|
277
|
+
refreshToken: tokens.refresh_token,
|
|
278
|
+
accessTokenExpiresAt,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
if (error instanceof Error && isBrowserClosedError(error)) {
|
|
283
|
+
throw new LoginCancelledError();
|
|
284
|
+
}
|
|
285
|
+
throw error;
|
|
286
|
+
}
|
|
287
|
+
finally {
|
|
288
|
+
page.off('close', closeHandler);
|
|
289
|
+
context.off('close', closeHandler);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Abstract base class for individual Google API services.
|
|
295
|
+
*
|
|
296
|
+
* Each subclass declares the specific API, scopes, and credential-check endpoint
|
|
297
|
+
* it needs. The OAuth and browser-prepare flows are handled here and scoped
|
|
298
|
+
* to that single API.
|
|
299
|
+
*/
|
|
300
|
+
export class GoogleService extends Service {
|
|
301
|
+
loginUrl = 'https://console.cloud.google.com/';
|
|
302
|
+
setCredentialsExample(serviceName) {
|
|
303
|
+
return `latchkey auth set ${serviceName} -H "Authorization: Bearer <token>"`;
|
|
304
|
+
}
|
|
305
|
+
getSession() {
|
|
306
|
+
return new GoogleServiceSession(this, this.config);
|
|
307
|
+
}
|
|
308
|
+
refreshCredentials(apiCredentials) {
|
|
309
|
+
if (!(apiCredentials instanceof OAuthCredentials)) {
|
|
310
|
+
return Promise.resolve(null);
|
|
311
|
+
}
|
|
312
|
+
if (!apiCredentials.refreshToken) {
|
|
313
|
+
return Promise.resolve(null);
|
|
314
|
+
}
|
|
315
|
+
const tokens = refreshAccessToken(GOOGLE_TOKEN_ENDPOINT, apiCredentials.refreshToken, apiCredentials.clientId, apiCredentials.clientSecret);
|
|
316
|
+
if (tokens === null) {
|
|
317
|
+
return Promise.resolve(null);
|
|
318
|
+
}
|
|
319
|
+
const accessTokenExpiresAt = new Date(Date.now() + tokens.expires_in * 1000).toISOString();
|
|
320
|
+
return Promise.resolve(new OAuthCredentials(apiCredentials.clientId, apiCredentials.clientSecret, tokens.access_token, tokens.refresh_token ?? apiCredentials.refreshToken, accessTokenExpiresAt, apiCredentials.refreshTokenExpiresAt));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../../src/services/google/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { GoogleService, type GoogleServiceConfig } from './base.js';
|
|
2
|
+
export declare class GoogleCalendar extends GoogleService {
|
|
3
|
+
readonly name = "google-calendar";
|
|
4
|
+
readonly displayName = "Google Calendar";
|
|
5
|
+
readonly baseApiUrls: readonly ["https://www.googleapis.com/calendar/"];
|
|
6
|
+
readonly info: string;
|
|
7
|
+
readonly credentialCheckCurlArguments: readonly ["https://www.googleapis.com/calendar/v3/calendars/primary"];
|
|
8
|
+
protected readonly config: GoogleServiceConfig;
|
|
9
|
+
}
|
|
10
|
+
export declare const GOOGLE_CALENDAR: GoogleCalendar;
|
|
11
|
+
//# sourceMappingURL=calendar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../../../src/services/google/calendar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAUpE,qBAAa,cAAe,SAAQ,aAAa;IAC/C,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,WAAW,qBAAqB;IACzC,QAAQ,CAAC,WAAW,oDAAqD;IACzE,QAAQ,CAAC,IAAI,SAG0D;IAEvE,QAAQ,CAAC,4BAA4B,wEAE1B;IAEX,SAAS,CAAC,QAAQ,CAAC,MAAM,sBAAU;CACpC;AAED,eAAO,MAAM,eAAe,gBAAuB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { GoogleService } from './base.js';
|
|
2
|
+
const CONFIG = {
|
|
3
|
+
api: 'calendar-json.googleapis.com',
|
|
4
|
+
scopes: [
|
|
5
|
+
'https://www.googleapis.com/auth/calendar',
|
|
6
|
+
'https://www.googleapis.com/auth/calendar.events',
|
|
7
|
+
],
|
|
8
|
+
};
|
|
9
|
+
export class GoogleCalendar extends GoogleService {
|
|
10
|
+
name = 'google-calendar';
|
|
11
|
+
displayName = 'Google Calendar';
|
|
12
|
+
baseApiUrls = ['https://www.googleapis.com/calendar/'];
|
|
13
|
+
info = 'https://developers.google.com/calendar/api/v3/reference. ' +
|
|
14
|
+
'If needed, run "latchkey auth browser-prepare google-calendar" to create an OAuth client first. ' +
|
|
15
|
+
'It may take a few minutes before the OAuth client is ready to use.';
|
|
16
|
+
credentialCheckCurlArguments = [
|
|
17
|
+
'https://www.googleapis.com/calendar/v3/calendars/primary',
|
|
18
|
+
];
|
|
19
|
+
config = CONFIG;
|
|
20
|
+
}
|
|
21
|
+
export const GOOGLE_CALENDAR = new GoogleCalendar();
|
|
22
|
+
//# sourceMappingURL=calendar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.js","sourceRoot":"","sources":["../../../../src/services/google/calendar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA4B,MAAM,WAAW,CAAC;AAEpE,MAAM,MAAM,GAAwB;IAClC,GAAG,EAAE,8BAA8B;IACnC,MAAM,EAAE;QACN,0CAA0C;QAC1C,iDAAiD;KAClD;CACF,CAAC;AAEF,MAAM,OAAO,cAAe,SAAQ,aAAa;IACtC,IAAI,GAAG,iBAAiB,CAAC;IACzB,WAAW,GAAG,iBAAiB,CAAC;IAChC,WAAW,GAAG,CAAC,sCAAsC,CAAU,CAAC;IAChE,IAAI,GACX,2DAA2D;QAC3D,kGAAkG;QAClG,oEAAoE,CAAC;IAE9D,4BAA4B,GAAG;QACtC,0DAA0D;KAClD,CAAC;IAEQ,MAAM,GAAG,MAAM,CAAC;CACpC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ApiCredentials } from '../../apiCredentials.js';
|
|
2
|
+
import { Service } from '../base.js';
|
|
3
|
+
export declare class GoogleDirections extends Service {
|
|
4
|
+
readonly name = "google-directions";
|
|
5
|
+
readonly displayName = "Google Directions";
|
|
6
|
+
readonly baseApiUrls: readonly ["https://routes.googleapis.com/"];
|
|
7
|
+
readonly loginUrl = "https://console.cloud.google.com/google/maps-apis/";
|
|
8
|
+
readonly info: string;
|
|
9
|
+
readonly credentialCheckCurlArguments: readonly ["-X", "POST", "-H", "Content-Type: application/json", "-H", "X-Goog-FieldMask: routes.duration", "-d", "{\"origin\":{\"location\":{\"latLng\":{\"latitude\":37.419734,\"longitude\":-122.0827784}}},\"destination\":{\"location\":{\"latLng\":{\"latitude\":37.417670,\"longitude\":-122.079595}}},\"travelMode\":\"DRIVE\"}", "https://routes.googleapis.com/directions/v2:computeRoutes"];
|
|
10
|
+
setCredentialsExample(serviceName: string): string;
|
|
11
|
+
getCredentialsNoCurl(arguments_: readonly string[]): ApiCredentials;
|
|
12
|
+
}
|
|
13
|
+
export declare const GOOGLE_DIRECTIONS: GoogleDirections;
|
|
14
|
+
//# sourceMappingURL=directions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directions.d.ts","sourceRoot":"","sources":["../../../../src/services/google/directions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAsC,MAAM,YAAY,CAAC;AAGzE,qBAAa,gBAAiB,SAAQ,OAAO;IAC3C,QAAQ,CAAC,IAAI,uBAAuB;IACpC,QAAQ,CAAC,WAAW,uBAAuB;IAC3C,QAAQ,CAAC,WAAW,8CAA+C;IACnE,QAAQ,CAAC,QAAQ,wDAAwD;IACzE,QAAQ,CAAC,IAAI,SAOkC;IAE/C,QAAQ,CAAC,4BAA4B,wYAU1B;IAEX,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAIzC,oBAAoB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,cAAc;CAe7E;AAUD,eAAO,MAAM,iBAAiB,kBAAyB,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Service, NoCurlCredentialsNotSupportedError } from '../base.js';
|
|
2
|
+
import { GoogleApiKeyCredentials } from './base.js';
|
|
3
|
+
export class GoogleDirections extends Service {
|
|
4
|
+
name = 'google-directions';
|
|
5
|
+
displayName = 'Google Directions';
|
|
6
|
+
baseApiUrls = ['https://routes.googleapis.com/'];
|
|
7
|
+
loginUrl = 'https://console.cloud.google.com/google/maps-apis/';
|
|
8
|
+
info = 'https://developers.google.com/maps/documentation/routes/reference/rest. ' +
|
|
9
|
+
'Example invocation: `latchkey curl google-directions -X POST ' +
|
|
10
|
+
'-H "Content-Type: application/json" ' +
|
|
11
|
+
'-H "X-Goog-FieldMask: routes.duration,routes.distanceMeters" ' +
|
|
12
|
+
'-d \'{"origin":{"address":"New York"},"destination":{"address":"Boston"},"travelMode":"DRIVE"}\' ' +
|
|
13
|
+
'https://routes.googleapis.com/directions/v2:computeRoutes` ' +
|
|
14
|
+
'(the API key will be added automatically).';
|
|
15
|
+
credentialCheckCurlArguments = [
|
|
16
|
+
'-X',
|
|
17
|
+
'POST',
|
|
18
|
+
'-H',
|
|
19
|
+
'Content-Type: application/json',
|
|
20
|
+
'-H',
|
|
21
|
+
'X-Goog-FieldMask: routes.duration',
|
|
22
|
+
'-d',
|
|
23
|
+
'{"origin":{"location":{"latLng":{"latitude":37.419734,"longitude":-122.0827784}}},"destination":{"location":{"latLng":{"latitude":37.417670,"longitude":-122.079595}}},"travelMode":"DRIVE"}',
|
|
24
|
+
'https://routes.googleapis.com/directions/v2:computeRoutes',
|
|
25
|
+
];
|
|
26
|
+
setCredentialsExample(serviceName) {
|
|
27
|
+
return `latchkey auth set-nocurl ${serviceName} <api-key>`;
|
|
28
|
+
}
|
|
29
|
+
getCredentialsNoCurl(arguments_) {
|
|
30
|
+
if (arguments_.length !== 1 || arguments_[0] === undefined) {
|
|
31
|
+
throw new GoogleDirectionsCredentialError('Expected exactly one argument: the API key.\n' +
|
|
32
|
+
'Example: latchkey auth set-nocurl google-directions <api-key>');
|
|
33
|
+
}
|
|
34
|
+
const apiKey = arguments_[0];
|
|
35
|
+
if (apiKey.length < 10) {
|
|
36
|
+
throw new GoogleDirectionsCredentialError("The provided key doesn't look like a Google API key (too short).\n" + 'Example: <api-key>');
|
|
37
|
+
}
|
|
38
|
+
return new GoogleApiKeyCredentials(apiKey);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
class GoogleDirectionsCredentialError extends NoCurlCredentialsNotSupportedError {
|
|
42
|
+
constructor(message) {
|
|
43
|
+
super('google-directions');
|
|
44
|
+
this.message = message;
|
|
45
|
+
this.name = 'GoogleDirectionsCredentialError';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export const GOOGLE_DIRECTIONS = new GoogleDirections();
|
|
49
|
+
//# sourceMappingURL=directions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directions.js","sourceRoot":"","sources":["../../../../src/services/google/directions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,kCAAkC,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAEpD,MAAM,OAAO,gBAAiB,SAAQ,OAAO;IAClC,IAAI,GAAG,mBAAmB,CAAC;IAC3B,WAAW,GAAG,mBAAmB,CAAC;IAClC,WAAW,GAAG,CAAC,gCAAgC,CAAU,CAAC;IAC1D,QAAQ,GAAG,oDAAoD,CAAC;IAChE,IAAI,GACX,0EAA0E;QAC1E,+DAA+D;QAC/D,sCAAsC;QACtC,+DAA+D;QAC/D,mGAAmG;QACnG,6DAA6D;QAC7D,4CAA4C,CAAC;IAEtC,4BAA4B,GAAG;QACtC,IAAI;QACJ,MAAM;QACN,IAAI;QACJ,gCAAgC;QAChC,IAAI;QACJ,mCAAmC;QACnC,IAAI;QACJ,8LAA8L;QAC9L,2DAA2D;KACnD,CAAC;IAEX,qBAAqB,CAAC,WAAmB;QACvC,OAAO,4BAA4B,WAAW,YAAY,CAAC;IAC7D,CAAC;IAEQ,oBAAoB,CAAC,UAA6B;QACzD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YAC3D,MAAM,IAAI,+BAA+B,CACvC,+CAA+C;gBAC7C,+DAA+D,CAClE,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACvB,MAAM,IAAI,+BAA+B,CACvC,oEAAoE,GAAG,oBAAoB,CAC5F,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;CACF;AAED,MAAM,+BAAgC,SAAQ,kCAAkC;IAC9E,YAAY,OAAe;QACzB,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,iCAAiC,CAAC;IAChD,CAAC;CACF;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { GoogleService, type GoogleServiceConfig } from './base.js';
|
|
2
|
+
export declare class GoogleDocs extends GoogleService {
|
|
3
|
+
readonly name = "google-docs";
|
|
4
|
+
readonly displayName = "Google Docs";
|
|
5
|
+
readonly baseApiUrls: readonly ["https://docs.googleapis.com/"];
|
|
6
|
+
readonly info: string;
|
|
7
|
+
readonly credentialCheckCurlArguments: readonly ["https://www.googleapis.com/drive/v3/files?pageSize=1&fields=files(id)&q=mimeType%3D'application/vnd.google-apps.document'"];
|
|
8
|
+
protected readonly config: GoogleServiceConfig;
|
|
9
|
+
}
|
|
10
|
+
export declare const GOOGLE_DOCS: GoogleDocs;
|
|
11
|
+
//# sourceMappingURL=docs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../../../src/services/google/docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAOpE,qBAAa,UAAW,SAAQ,aAAa;IAC3C,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,WAAW,iBAAiB;IACrC,QAAQ,CAAC,WAAW,4CAA6C;IACjE,QAAQ,CAAC,IAAI,SAG0D;IAEvE,QAAQ,CAAC,4BAA4B,yIAE1B;IAEX,SAAS,CAAC,QAAQ,CAAC,MAAM,sBAAU;CACpC;AAED,eAAO,MAAM,WAAW,YAAmB,CAAC"}
|