From 1edf801b024ebe32bd7f18cfa420320e618e3221 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Tue, 5 Mar 2024 16:13:50 +0800 Subject: [PATCH] add settings jsonb column to the integrations --- packages/api/src/entity/integration.ts | 3 +++ packages/api/src/generated/graphql.ts | 7 +++++++ packages/api/src/generated/schema.graphql | 4 ++++ packages/api/src/jobs/integration/export_item.ts | 6 +++++- packages/api/src/resolvers/integrations/index.ts | 8 +++++++- packages/api/src/routers/integration_router.ts | 2 +- packages/api/src/schema.ts | 2 ++ packages/api/src/services/integrations/index.ts | 5 +++-- packages/api/src/services/integrations/notion.ts | 8 +++++++- .../0167.do.add_settings_column_to_integrations.sql | 9 +++++++++ .../0167.undo.add_settings_column_to_integrations.sql | 9 +++++++++ 11 files changed, 57 insertions(+), 6 deletions(-) create mode 100755 packages/db/migrations/0167.do.add_settings_column_to_integrations.sql create mode 100755 packages/db/migrations/0167.undo.add_settings_column_to_integrations.sql diff --git a/packages/api/src/entity/integration.ts b/packages/api/src/entity/integration.ts index e446f10c3..dcb7f03c1 100644 --- a/packages/api/src/entity/integration.ts +++ b/packages/api/src/entity/integration.ts @@ -59,4 +59,7 @@ export class Integration { @Column('enum', { enum: ImportItemState, nullable: true }) importItemState?: ImportItemState | null + + @Column('jsonb', { nullable: true }) + settings?: any } diff --git a/packages/api/src/generated/graphql.ts b/packages/api/src/generated/graphql.ts index 581880e4f..ec46d4c65 100644 --- a/packages/api/src/generated/graphql.ts +++ b/packages/api/src/generated/graphql.ts @@ -1085,6 +1085,7 @@ export type Integration = { enabled: Scalars['Boolean']; id: Scalars['ID']; name: Scalars['String']; + settings?: Maybe; taskName?: Maybe; token: Scalars['String']; type: IntegrationType; @@ -2404,6 +2405,7 @@ export enum SearchErrorCode { export type SearchItem = { __typename?: 'SearchItem'; + aiSummary?: Maybe; annotation?: Maybe; archivedAt?: Maybe; author?: Maybe; @@ -2586,6 +2588,7 @@ export type SetIntegrationInput = { id?: InputMaybe; importItemState?: InputMaybe; name: Scalars['String']; + settings?: InputMaybe; syncedAt?: InputMaybe; taskName?: InputMaybe; token: Scalars['String']; @@ -3378,6 +3381,7 @@ export enum UploadImportFileType { export type User = { __typename?: 'User'; email?: Maybe; + features?: Maybe>>; followersCount?: Maybe; friendsCount?: Maybe; id: Scalars['ID']; @@ -5310,6 +5314,7 @@ export type IntegrationResolvers; id?: Resolver; name?: Resolver; + settings?: Resolver, ParentType, ContextType>; taskName?: Resolver, ParentType, ContextType>; token?: Resolver; type?: Resolver; @@ -5945,6 +5950,7 @@ export type SearchErrorResolvers = { + aiSummary?: Resolver, ParentType, ContextType>; annotation?: Resolver, ParentType, ContextType>; archivedAt?: Resolver, ParentType, ContextType>; author?: Resolver, ParentType, ContextType>; @@ -6528,6 +6534,7 @@ export type UploadImportFileSuccessResolvers = { email?: Resolver, ParentType, ContextType>; + features?: Resolver>>, ParentType, ContextType>; followersCount?: Resolver, ParentType, ContextType>; friendsCount?: Resolver, ParentType, ContextType>; id?: Resolver; diff --git a/packages/api/src/generated/schema.graphql b/packages/api/src/generated/schema.graphql index b344a250a..bf37f919d 100644 --- a/packages/api/src/generated/schema.graphql +++ b/packages/api/src/generated/schema.graphql @@ -968,6 +968,7 @@ type Integration { enabled: Boolean! id: ID! name: String! + settings: JSON taskName: String token: String! type: IntegrationType! @@ -1832,6 +1833,7 @@ enum SearchErrorCode { } type SearchItem { + aiSummary: String annotation: String archivedAt: Date author: String @@ -2001,6 +2003,7 @@ input SetIntegrationInput { id: ID importItemState: ImportItemState name: String! + settings: JSON syncedAt: Date taskName: String token: String! @@ -2733,6 +2736,7 @@ enum UploadImportFileType { type User { email: String + features: [String] followersCount: Int friendsCount: Int id: ID! diff --git a/packages/api/src/jobs/integration/export_item.ts b/packages/api/src/jobs/integration/export_item.ts index a1b8f7cc2..277ff5a9a 100644 --- a/packages/api/src/jobs/integration/export_item.ts +++ b/packages/api/src/jobs/integration/export_item.ts @@ -44,7 +44,11 @@ export const exportItem = async (jobData: ExportItemJobData) => { } logger.info('exporting item...', logObject) - const client = getIntegrationClient(integration.name, integration.token) + const client = getIntegrationClient( + integration.name, + integration.token, + integration.settings + ) const synced = await client.export(libraryItems) if (!synced) { diff --git a/packages/api/src/resolvers/integrations/index.ts b/packages/api/src/resolvers/integrations/index.ts index 5148d0893..5d2a01525 100644 --- a/packages/api/src/resolvers/integrations/index.ts +++ b/packages/api/src/resolvers/integrations/index.ts @@ -55,6 +55,8 @@ export const setIntegrationResolver = authorized< input.type === IntegrationType.Import ? input.importItemState || ImportItemState.Unarchived // default to unarchived : undefined, + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + settings: input.settings, } if (input.id) { // Update @@ -69,7 +71,11 @@ export const setIntegrationResolver = authorized< integrationToSave.taskName = existingIntegration.taskName } else { // Create - const integrationService = getIntegrationClient(input.name, input.token) + const integrationService = getIntegrationClient( + input.name, + input.token, + input.settings + ) // authorize and get access token const token = await integrationService.accessToken() if (!token) { diff --git a/packages/api/src/routers/integration_router.ts b/packages/api/src/routers/integration_router.ts index 7bf5cbdc6..82645b8de 100644 --- a/packages/api/src/routers/integration_router.ts +++ b/packages/api/src/routers/integration_router.ts @@ -21,7 +21,7 @@ export function integrationRouter() { return res.status(401).send('UNAUTHORIZED') } - const integrationClient = getIntegrationClient(req.params.name, '') + const integrationClient = getIntegrationClient(req.params.name, '', null) // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access const state = req.body.state as string diff --git a/packages/api/src/schema.ts b/packages/api/src/schema.ts index 86b1f46e2..aec8756e9 100755 --- a/packages/api/src/schema.ts +++ b/packages/api/src/schema.ts @@ -2008,6 +2008,7 @@ const schema = gql` createdAt: Date! updatedAt: Date taskName: String + settings: JSON } enum IntegrationType { @@ -2043,6 +2044,7 @@ const schema = gql` syncedAt: Date importItemState: ImportItemState taskName: String + settings: JSON } union IntegrationsResult = IntegrationsSuccess | IntegrationsError diff --git a/packages/api/src/services/integrations/index.ts b/packages/api/src/services/integrations/index.ts index 953199052..aa59f900b 100644 --- a/packages/api/src/services/integrations/index.ts +++ b/packages/api/src/services/integrations/index.ts @@ -8,7 +8,8 @@ import { ReadwiseClient } from './readwise' export const getIntegrationClient = ( name: string, - token: string + token: string, + settings: any ): IntegrationClient => { switch (name.toLowerCase()) { case 'readwise': @@ -16,7 +17,7 @@ export const getIntegrationClient = ( case 'pocket': return new PocketClient(token) case 'notion': - return new NotionClient(token) + return new NotionClient(token, settings) default: throw new Error(`Integration client not found: ${name}`) } diff --git a/packages/api/src/services/integrations/notion.ts b/packages/api/src/services/integrations/notion.ts index 868a5ec57..085c20566 100644 --- a/packages/api/src/services/integrations/notion.ts +++ b/packages/api/src/services/integrations/notion.ts @@ -23,6 +23,10 @@ interface NotionPage { } } +interface Settings { + parentPageId: string +} + export class NotionClient implements IntegrationClient { name = 'NOTION' _headers = { @@ -39,13 +43,15 @@ export class NotionClient implements IntegrationClient { _token: string _client: Client + _settings: Settings - constructor(token: string) { + constructor(token: string, settings: Settings) { this._token = token this._client = new Client({ auth: token, timeoutMs: this._timeout, }) + this._settings = settings } accessToken = async (): Promise => { diff --git a/packages/db/migrations/0167.do.add_settings_column_to_integrations.sql b/packages/db/migrations/0167.do.add_settings_column_to_integrations.sql new file mode 100755 index 000000000..d8c2521b8 --- /dev/null +++ b/packages/db/migrations/0167.do.add_settings_column_to_integrations.sql @@ -0,0 +1,9 @@ +-- Type: DO +-- Name: add_settings_column_to_integrations +-- Description: Add settings column to integrations table + +BEGIN; + +ALTER TABLE omnivore.integrations ADD COLUMN settings jsonb; + +COMMIT; diff --git a/packages/db/migrations/0167.undo.add_settings_column_to_integrations.sql b/packages/db/migrations/0167.undo.add_settings_column_to_integrations.sql new file mode 100755 index 000000000..34a03ae7e --- /dev/null +++ b/packages/db/migrations/0167.undo.add_settings_column_to_integrations.sql @@ -0,0 +1,9 @@ +-- Type: UNDO +-- Name: add_settings_column_to_integrations +-- Description: Add settings column to integrations table + +BEGIN; + +ALTER TABLE omnivore.integrations DROP COLUMN settings; + +COMMIT;