add settings jsonb column to the integrations

This commit is contained in:
Hongbo Wu 2024-03-05 16:13:50 +08:00
parent f1b1f2c4c1
commit 1edf801b02
11 changed files with 57 additions and 6 deletions

View file

@ -59,4 +59,7 @@ export class Integration {
@Column('enum', { enum: ImportItemState, nullable: true })
importItemState?: ImportItemState | null
@Column('jsonb', { nullable: true })
settings?: any
}

View file

@ -1085,6 +1085,7 @@ export type Integration = {
enabled: Scalars['Boolean'];
id: Scalars['ID'];
name: Scalars['String'];
settings?: Maybe<Scalars['JSON']>;
taskName?: Maybe<Scalars['String']>;
token: Scalars['String'];
type: IntegrationType;
@ -2404,6 +2405,7 @@ export enum SearchErrorCode {
export type SearchItem = {
__typename?: 'SearchItem';
aiSummary?: Maybe<Scalars['String']>;
annotation?: Maybe<Scalars['String']>;
archivedAt?: Maybe<Scalars['Date']>;
author?: Maybe<Scalars['String']>;
@ -2586,6 +2588,7 @@ export type SetIntegrationInput = {
id?: InputMaybe<Scalars['ID']>;
importItemState?: InputMaybe<ImportItemState>;
name: Scalars['String'];
settings?: InputMaybe<Scalars['JSON']>;
syncedAt?: InputMaybe<Scalars['Date']>;
taskName?: InputMaybe<Scalars['String']>;
token: Scalars['String'];
@ -3378,6 +3381,7 @@ export enum UploadImportFileType {
export type User = {
__typename?: 'User';
email?: Maybe<Scalars['String']>;
features?: Maybe<Array<Maybe<Scalars['String']>>>;
followersCount?: Maybe<Scalars['Int']>;
friendsCount?: Maybe<Scalars['Int']>;
id: Scalars['ID'];
@ -5310,6 +5314,7 @@ export type IntegrationResolvers<ContextType = ResolverContext, ParentType exten
enabled?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>;
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
name?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
settings?: Resolver<Maybe<ResolversTypes['JSON']>, ParentType, ContextType>;
taskName?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
token?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
type?: Resolver<ResolversTypes['IntegrationType'], ParentType, ContextType>;
@ -5945,6 +5950,7 @@ export type SearchErrorResolvers<ContextType = ResolverContext, ParentType exten
};
export type SearchItemResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['SearchItem'] = ResolversParentTypes['SearchItem']> = {
aiSummary?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
annotation?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
archivedAt?: Resolver<Maybe<ResolversTypes['Date']>, ParentType, ContextType>;
author?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
@ -6528,6 +6534,7 @@ export type UploadImportFileSuccessResolvers<ContextType = ResolverContext, Pare
export type UserResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['User'] = ResolversParentTypes['User']> = {
email?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
features?: Resolver<Maybe<Array<Maybe<ResolversTypes['String']>>>, ParentType, ContextType>;
followersCount?: Resolver<Maybe<ResolversTypes['Int']>, ParentType, ContextType>;
friendsCount?: Resolver<Maybe<ResolversTypes['Int']>, ParentType, ContextType>;
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;

View file

@ -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!

View file

@ -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) {

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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}`)
}

View file

@ -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<string | null> => {

View file

@ -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;

View file

@ -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;