diff --git a/examples/database-email-update/package.json b/examples/database-email-update/package.json index 39805bf6..0f74c888 100644 --- a/examples/database-email-update/package.json +++ b/examples/database-email-update/package.json @@ -13,7 +13,7 @@ "dependencies": { "@sendgrid/mail": "^7.4.5", "dotenv": "^10.0.0", - "@notionhq/client": "^0.3.0" + "@notionhq/client": "^0.3.1" }, "author": "Aman Gupta", "license": "MIT" diff --git a/examples/notion-github-sync/package.json b/examples/notion-github-sync/package.json index a52abdd7..7b6e064b 100644 --- a/examples/notion-github-sync/package.json +++ b/examples/notion-github-sync/package.json @@ -13,7 +13,7 @@ "author": "Aman Gupta", "license": "MIT", "dependencies": { - "@notionhq/client": "^0.3.0", + "@notionhq/client": "^0.3.1", "dotenv": "^10.0.0", "lodash": "^4.17.21", "octokit": "^1.1.0" diff --git a/package.json b/package.json index 94fe9455..f6afe7dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@notionhq/client", - "version": "0.3.0", + "version": "0.3.1", "description": "A simple and easy to use client for the Notion API", "engines": { "node": ">=12" diff --git a/src/api-endpoints.ts b/src/api-endpoints.ts index b5b55b5c..8c96df49 100644 --- a/src/api-endpoints.ts +++ b/src/api-endpoints.ts @@ -28,7 +28,11 @@ import { RichTextInput, UpdateBlock, UpdatePropertySchema, + ExternalFileInput, + EmojiInput, + FileInput, } from "./api-types" +import { DistributiveOmit } from "./type-utils" // TODO: type assertions to verify that each interface is synchronized to the list of keys in the runtime value below. @@ -228,10 +232,29 @@ export type PropertyValueMap = { [propertyName: string]: PropertyValue } export type InputPropertyValueMap = { [propertyName: string]: InputPropertyValue } + +export type PageIcon = FileInput | ExternalFileInput | EmojiInput + +export type PageIconInput = + | (DistributiveOmit, "type"> & { + type?: string + }) + | null + +export type PageCover = FileInput | ExternalFileInput + +export type PageCoverInput = + | (DistributiveOmit, "type"> & { + type?: string + }) + | null + interface PagesCreateBodyParameters { parent: ParentInput properties: InputPropertyValueMap children?: Block[] + icon?: PageIconInput + cover?: PageCoverInput } export interface PagesCreateParameters @@ -244,7 +267,7 @@ export const pagesCreate = { method: "post", pathParams: [], queryParams: [], - bodyParams: ["parent", "properties", "children"], + bodyParams: ["parent", "properties", "children", "icon", "cover"], path: () => `pages`, } as const @@ -262,6 +285,8 @@ interface DatabasesCreateBodyParameters { parent: ParentPageInput properties: InputPropertySchemaMap title?: RichTextInput[] + icon?: PageIconInput + cover?: PageCoverInput } export interface DatabasesCreateParameters @@ -274,7 +299,7 @@ export const databasesCreate = { method: "post", pathParams: [], queryParams: [], - bodyParams: ["parent", "properties", "title"], + bodyParams: ["parent", "properties", "title", "icon", "cover"], path: () => `databases`, } as const @@ -293,6 +318,8 @@ export type UpdatePropertySchemaMap = { interface DatabasesUpdateBodyParameters { properties?: UpdatePropertySchemaMap title?: RichTextInput[] + icon?: PageIconInput + cover?: PageCoverInput } export interface DatabasesUpdateParameters @@ -305,7 +332,7 @@ export const databasesUpdate = { method: "patch", pathParams: ["database_id"], queryParams: [], - bodyParams: ["properties", "title"], + bodyParams: ["properties", "title", "icon", "cover"], path: (d: DatabasesUpdatePathParameters) => `databases/${d.database_id}`, } as const @@ -345,22 +372,24 @@ interface PagesUpdateQueryParameters {} interface PagesUpdateBodyArchiveParameter { archived: boolean } -interface PagesUpdateBodyPropertiesParameters { +interface PagesUpdateBodyParameters { properties: InputPropertyValueMap + icon?: PageIconInput + cover?: PageCoverInput } export interface PagesUpdateParameters extends PagesUpdatePathParameters, PagesUpdateQueryParameters, PagesUpdateBodyArchiveParameter, - PagesUpdateBodyPropertiesParameters {} + PagesUpdateBodyParameters {} export interface PagesUpdateResponse extends Page {} export const pagesUpdate = { method: "patch", pathParams: ["page_id"], queryParams: [], - bodyParams: ["archived", "properties"], + bodyParams: ["archived", "properties", "cover", "icon"], path: (p: PagesUpdatePathParameters) => `pages/${p.page_id}`, } as const diff --git a/src/api-types.ts b/src/api-types.ts index 25898805..ae41588e 100644 --- a/src/api-types.ts +++ b/src/api-types.ts @@ -6,7 +6,12 @@ */ import { PropertyValueMap } from "./api-endpoints" -import { DistributiveExtend, DistributiveOmit, RequiredBy } from "./type-utils" +import { + DistributiveExtend, + DistributiveOmit, + PartialBy, + RequiredBy, +} from "./type-utils" /* * Pagination @@ -49,6 +54,12 @@ export type Block = | ToDoBlock | ToggleBlock | ChildPageBlock + | EmbedBlock + | ImageBlock + | VideoBlock + | FileBlock + | PDFBlock + | AudioBlock | UnsupportedBlock export interface BlockBase { @@ -124,6 +135,47 @@ export interface ChildPageBlock extends BlockBase { child_page: { title: string } } +export interface EmbedBlock extends BlockBase { + type: "embed" + embed: { + url: string + caption?: RichText[] + } +} + +export interface ExternalFileWithCaption extends ExternalFile { + caption?: RichText[] +} + +export interface FileWithCaption extends File { + caption?: RichText[] +} + +export interface ImageBlock extends BlockBase { + type: "image" + image: ExternalFileWithCaption | FileWithCaption +} + +export interface VideoBlock extends BlockBase { + type: "video" + video: ExternalFileWithCaption | FileWithCaption +} + +export interface FileBlock extends BlockBase { + type: "file" + file: ExternalFileWithCaption | FileWithCaption +} + +export interface PDFBlock extends BlockBase { + type: "pdf" + pdf: ExternalFileWithCaption | FileWithCaption +} + +export interface AudioBlock extends BlockBase { + type: "audio" + audio: ExternalFileWithCaption | FileWithCaption +} + export interface UnsupportedBlock extends BlockBase { type: "unsupported" } @@ -139,6 +191,8 @@ export interface Database { created_time: string last_edited_time: string title: RichText[] + icon: File | ExternalFile | Emoji | null + cover: File | ExternalFile | null properties: { [propertyName: string]: Property } } @@ -565,6 +619,8 @@ export interface Page { created_time: string last_edited_time: string archived: boolean + icon: File | ExternalFile | Emoji | null + cover: File | ExternalFile | null properties: PropertyValueMap url: string } @@ -686,7 +742,7 @@ export type InputPropertyValueWithRequiredId = | FormulaPropertyValue | RollupPropertyValue | PeoplePropertyValue - | FilesPropertyValue + | FilesPropertyInputValue | CheckboxPropertyValue | URLPropertyValue | EmailPropertyValue @@ -793,9 +849,23 @@ export interface PeoplePropertyValue extends PropertyValueBase { people: User[] } +type FileWithName = { + name: string +} & (File | ExternalFile) + +type ExternalFileWithName = { + name: string +} & ExternalFile + export interface FilesPropertyValue extends PropertyValueBase { type: "files" - files: { name: string }[] + files: FileWithName[] +} + +// When writing, we don't allow S3 hosted files +export interface FilesPropertyInputValue extends PropertyValueBase { + type: "files" + files: ExternalFileWithName[] } export interface CheckboxPropertyValue extends PropertyValueBase { @@ -1064,3 +1134,34 @@ export type UpdatePropertySchema = | UpdateMultiSelectPropertySchema | RenamePropertySchema | null + +/* + * Files + */ + +interface FileBase { + type: "file" + file: { + url: string + } +} + +export type File = FileBase & { file: { expiry_time: string } } + +export type FileInput = PartialBy + +export interface ExternalFile { + type: "external" + external: { + url: string + } +} + +export type ExternalFileInput = PartialBy + +export interface Emoji { + type: "emoji" + emoji: string +} + +export type EmojiInput = PartialBy