chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:34:48 +08:00
commit 77bb5bf71f
3762 changed files with 353249 additions and 0 deletions
@@ -0,0 +1,31 @@
import type { NotionPagePropertyTypes } from '../types'
/**
* the properties with type `null` cannot be updated via the API
*/
export const NOTION_PROPERTY_STRINGIFIED_TYPE_MAP: Record<NotionPagePropertyTypes, string> = {
date: '{start:string;end:string}',
url: 'string',
select: '{name:string}',
phone_number: 'string',
checkbox: '{start:string;end:string}',
files: 'Array<{name:string;external:{url:string}}>',
email: 'string',
number: 'number',
title: 'Array<{type:"text",text:{content:string;link:null}}>',
created_time: '{start:string;end:string}',
last_edited_time: 'null',
last_edited_by: 'null',
rich_text: 'Array<{type:"text",text:{content:string;link:null}}>',
people: 'Array<{object:"user";id:string}>',
relation: 'Array<{id:string}>',
rollup: 'null',
formula: 'null',
multi_select: 'Array<{name:string}>',
created_by: '{start:string;end:string}',
status: '{name:string}',
unique_id: '{start:string;end:string}',
button: 'null',
verification: 'null',
place: 'null',
}
@@ -0,0 +1,8 @@
import { expect, test } from 'vitest'
import { MOCK_RESPONSE_1, MOCK_RESPONSE_1_PROCESSED } from './fixtures/mock-responses'
import { getDbStructure } from './db-structure'
test('getDBStructure', () => {
const structure = getDbStructure(MOCK_RESPONSE_1)
expect(structure).toBe(MOCK_RESPONSE_1_PROCESSED)
})
@@ -0,0 +1,31 @@
import type { GetDataSourceResponse } from '@notionhq/client/build/src/api-endpoints'
import { NOTION_PROPERTY_STRINGIFIED_TYPE_MAP } from './consts'
/**
* @returns a stringified type definition of the database properties
* This can be useful when instructing GPT to parse some data to fit the db model
* which can be then passed as properties to `addPageToDb`
*
* These are based on the [Notion Page Properties](https://developers.notion.com/reference/page-property-values)
*/
export function getDbStructure(response: GetDataSourceResponse): string {
// Ensure we have a full response with properties
if (!('properties' in response)) {
return '{}'
}
const properties = Object.entries(response.properties)
const stringifiedTypes: string = properties.reduce((_stringifiedTypes, [key, value], index) => {
_stringifiedTypes += `${key}:{type:"${value.type}";"${value.type}":${
NOTION_PROPERTY_STRINGIFIED_TYPE_MAP[value.type]
}}`
if (index === properties.length - 1) {
_stringifiedTypes += '}'
} else {
_stringifiedTypes += ','
}
return _stringifiedTypes
}, '{')
return stringifiedTypes
}
@@ -0,0 +1,169 @@
import { GetDataSourceResponse } from '@notionhq/client/build/src/api-endpoints'
import { NOTION_PROPERTY_STRINGIFIED_TYPE_MAP } from '../consts'
export const MOCK_RESPONSE_1: GetDataSourceResponse = {
object: 'data_source',
id: 'e819c5b1-77f8-4a7d-953c-3dc9e9c46037',
cover: {
type: 'external',
external: {
url: 'https://images.unsplash.com/photo-1546177461-79dfec0b0928?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1974&q=80',
},
},
icon: { type: 'external', external: { url: 'https://www.notion.so/icons/book-closed_lightgray.svg' } },
created_time: '2023-07-06T21:38:00.000Z',
created_by: { object: 'user', id: '2b76f457-7e30-4f66-8e74-da55469e64c8' },
last_edited_by: { object: 'user', id: '2b76f457-7e30-4f66-8e74-da55469e64c8' },
last_edited_time: '2023-07-07T00:30:00.000Z',
title: [
{
type: 'text',
text: { content: 'Reading List', link: null },
annotations: {
bold: false,
italic: false,
strikethrough: false,
underline: false,
code: false,
color: 'default',
},
plain_text: 'Reading List',
href: null,
},
],
description: [
{
type: 'text',
text: {
content:
"📚 The modern day reading list includes more than just books. We've created a dashboard to help you track books, articles, podcasts, and videos. Each media type has its own view based on the Type property. \n\n✂️ One more thing... if you install the ",
link: null,
},
annotations: {
bold: false,
italic: false,
strikethrough: false,
underline: false,
code: false,
color: 'default',
},
plain_text:
"📚 The modern day reading list includes more than just books. We've created a dashboard to help you track books, articles, podcasts, and videos. Each media type has its own view based on the Type property. \n\n✂️ One more thing... if you install the ",
href: null,
},
{
type: 'text',
text: { content: 'Notion Web Clipper', link: { url: 'https://www.notion.so/web-clipper' } },
annotations: {
bold: false,
italic: false,
strikethrough: false,
underline: false,
code: false,
color: 'default',
},
plain_text: 'Notion Web Clipper',
href: 'https://www.notion.so/web-clipper',
},
{
type: 'text',
text: {
content:
', you can save links off the web directly to this table.\n\n👇 Click through the different database tabs to see other views. Sort content by status, author, type, or publisher.',
link: null,
},
annotations: {
bold: false,
italic: false,
strikethrough: false,
underline: false,
code: false,
color: 'default',
},
plain_text:
', you can save links off the web directly to this table.\n\n👇 Click through the different database tabs to see other views. Sort content by status, author, type, or publisher.',
href: null,
},
],
is_inline: false,
properties: {
Score: {
id: ')Y7%22',
name: 'Score',
description: '',
type: 'select',
select: {
options: [
{ id: '5c944de7-3f4b-4567-b3a1-fa2c71c540b6', name: '⭐️⭐️⭐️⭐️⭐️', color: 'default', description: '' },
{ id: 'b7307e35-c80a-4cb5-bb6b-6054523b394a', name: '⭐️⭐️⭐️⭐️', color: 'default', description: '' },
{ id: '9b1e1349-8e24-40ba-bbca-84a61296bc81', name: '⭐️⭐️⭐️', color: 'default', description: '' },
{ id: '66d3d050-086c-4a91-8c56-d55dc67e7789', name: '⭐️⭐️', color: 'default', description: '' },
{ id: 'd3782c76-0396-467f-928e-46bf0c9d5fba', name: '⭐️', color: 'default', description: '' },
{ id: 'f8966551-1d96-4106-b0c5-7ca459029bab', name: 'TBD', color: 'default', description: '' },
],
},
},
Type: {
id: '%2F7eo',
name: 'Type',
description: '',
type: 'select',
select: {
options: [
{ id: '42a0b2e8-c8da-4e5d-a2f2-5ccba15d1034', name: 'Book', color: 'default', description: '' },
{ id: 'f96d0d0a-5564-4a20-ab15-5f040d49759e', name: 'Article', color: 'default', description: '' },
{ id: '4ac85597-5db1-4e0a-9c02-445575c38f76', name: 'TV Series', color: 'default', description: '' },
{ id: '2991748a-5745-4c3b-9c9b-2d6846a6fa1f', name: 'Film', color: 'default', description: '' },
{ id: '82f3bace-be25-410d-87fe-561c9c22492f', name: 'Podcast', color: 'default', description: '' },
{ id: '861f1076-1cc4-429a-a781-54947d727a4a', name: 'Academic Journal', color: 'default', description: '' },
{ id: '9cc30548-59d6-4cd3-94bc-d234081525c4', name: 'Essay Resource', color: 'default', description: '' },
],
},
},
Status: {
id: 'UMCM',
name: 'Status',
description: '',
type: 'status',
status: {
options: [
{ id: '387caf66-e381-4bfa-bddc-ef3c33b1670e', name: 'Not started', color: 'red', description: '' },
{ id: '2bbcb9a8-1df1-47b6-a6af-2dafbf814871', name: 'In progress', color: 'blue', description: '' },
{ id: 'aac65976-840a-47bd-8f97-782176d2d4f2', name: 'Done', color: 'green', description: '' },
],
groups: [
{
id: '7c521ba2-0e95-4bc2-95f6-48f6e44f1dc7',
name: 'To-do',
color: 'gray',
option_ids: ['387caf66-e381-4bfa-bddc-ef3c33b1670e'],
},
{
id: '4f3189a4-747d-4398-95ee-8b7c111a6f7a',
name: 'In progress',
color: 'blue',
option_ids: ['2bbcb9a8-1df1-47b6-a6af-2dafbf814871'],
},
{
id: 'b1ae6339-5453-45aa-8e00-b6e1b34e9064',
name: 'Complete',
color: 'green',
option_ids: ['aac65976-840a-47bd-8f97-782176d2d4f2'],
},
],
},
},
Link: { id: 'VVMi', name: 'Link', type: 'url', url: {}, description: '' },
Completed: { id: 'qGBj', name: 'Completed', type: 'date', date: {}, description: '' },
Author: { id: 'qNw_', name: 'Author', type: 'rich_text', rich_text: {}, description: '' },
Name: { id: 'title', name: 'Name', type: 'title', title: {}, description: '' },
},
parent: { type: 'data_source_id', data_source_id: 'parent-ds-id', database_id: 'parent-db-id' },
database_parent: { type: 'workspace', workspace: true },
in_trash: false,
url: 'https://www.notion.so/e819c5b177f84a7d953c3dc9e9c46037',
public_url: null,
archived: false,
}
export const MOCK_RESPONSE_1_PROCESSED = `{Score:{type:"select";"select":${NOTION_PROPERTY_STRINGIFIED_TYPE_MAP.select}},Type:{type:"select";"select":${NOTION_PROPERTY_STRINGIFIED_TYPE_MAP.select}},Status:{type:"status";"status":${NOTION_PROPERTY_STRINGIFIED_TYPE_MAP.status}},Link:{type:"url";"url":${NOTION_PROPERTY_STRINGIFIED_TYPE_MAP.url}},Completed:{type:"date";"date":${NOTION_PROPERTY_STRINGIFIED_TYPE_MAP.date}},Author:{type:"rich_text";"rich_text":${NOTION_PROPERTY_STRINGIFIED_TYPE_MAP.rich_text}},Name:{type:"title";"title":${NOTION_PROPERTY_STRINGIFIED_TYPE_MAP.title}}}`
@@ -0,0 +1 @@
export * from './db-structure'