UNPKG

notion-ts-client

Version:

Generates an easy to use and fully typed API to access and modify the data in Notion Databases

158 lines (132 loc) 4.91 kB
import { ConfigFilePropertiesConfig } from '../../types' import { saveContentToFile } from '../file-utils' const TYPE_INDENT = ' ' const PATCH_IGNORE_PROPS = ['created_by', 'created_time', 'last_edited_by', 'last_edited_time'] export function createPatchDTOFile(opts: { dbPath: string fileName: string dbTypeName: string propsConfig: ConfigFilePropertiesConfig }) { const imports = getDTOFileImports(opts.dbTypeName, opts.propsConfig) const type = getDTOFileType(opts.dbTypeName, opts.propsConfig) const code = getDTOFileCode(opts.propsConfig) const content = `${imports} type TypeFromRecord<Obj, Type> = Obj extends Record<string, infer T> ? Extract<T, Type> : never export type ${opts.dbTypeName}PropertiesPatch = { ${type}} export class ${opts.dbTypeName}PatchDTO { __data: UpdatePageBodyParameters constructor(opts: { properties?: ${opts.dbTypeName}PropertiesPatch coverUrl?: string icon?: UpdatePageBodyParameters['icon'] archived?: UpdatePageBodyParameters['archived'] }) { const { properties: props, coverUrl, icon, archived } = opts this.__data = {} this.__data.properties = {} this.__data.cover = coverUrl ? { type: 'external', external: { url: coverUrl } } : undefined this.__data.icon = icon this.__data.archived = archived ${code} } } ` saveContentToFile(content, opts.dbPath, opts.fileName) } function getDTOFileImports(dbTypeName: string, propsConfig: ConfigFilePropertiesConfig) { const imports = Object.values(propsConfig) .map((prop) => getImportType(prop._type)) .filter((i) => i !== undefined) const uniqueImports = Array.from(new Set(imports)).sort() return ( `import { ${dbTypeName}Response } from "./types" import { UpdatePageBodyParameters,\n` + uniqueImports.join(',\n') + `\n} from '../../core/types/notion-api.types'` ) } function getImportType(type: string) { switch (type) { case 'title': case 'rich_text': return 'RichTextItemRequest' } } function getDTOFileType(dbTypeName: string, dbPropsConfig: ConfigFilePropertiesConfig) { const content = Object.values(dbPropsConfig).reduce((acc, propConfig) => { let typeValue if ( PATCH_IGNORE_PROPS.includes(propConfig._type) || propConfig.readOnly || ['button', 'rollup'].includes(propConfig._type) ) { return acc } if (propConfig._type === 'multi_select') { typeValue = `${dbTypeName}Response['properties']['${propConfig._name}']['multi_select'][number]['name'][]` } else if (propConfig._type === 'select') { typeValue = `${dbTypeName}Response['properties']['${propConfig._name}']['select']['name']` } else if (['rich_text', 'title'].includes(propConfig._type)) { typeValue = `string | { text: string; url?: string; annotations?: RichTextItemRequest['annotations'] } | RichTextItemRequest[]` } else { typeValue = `TypeFromRecord<UpdatePageBodyParameters['properties'], { type?: '${propConfig._type}' }>['${propConfig._type}']` } acc += `${TYPE_INDENT}${propConfig.varName}?: ${typeValue}\n` return acc }, '') return content } function getDTOFileCode(dbPropsConfig: ConfigFilePropertiesConfig) { const content = Object.entries(dbPropsConfig).reduce((acc, [propId, propConfig]) => { let objValue if ( PATCH_IGNORE_PROPS.includes(propConfig._type) || propConfig.readOnly || ['button', 'rollup'].includes(propConfig._type) ) { return acc } if (propConfig._type === 'multi_select') { objValue = ` type: 'multi_select', multi_select: props.${propConfig.varName}?.map((item) => ({ name: item })),` } else if (propConfig._type === 'select') { objValue = ` type: 'select', select: { name: props.${propConfig.varName} },` } else if (['rich_text', 'title'].includes(propConfig._type)) { const propsVar = `props.${propConfig.varName}` objValue = ` type: '${propConfig._type}', ${propConfig._type}: typeof ${propsVar} === 'string' ? [{ type: 'text', text: { content: ${propsVar} } }] : Array.isArray(${propsVar}) ? ${propsVar} : ${propsVar} === null ? [] : [ { type: 'text', text: { content: ${propsVar}.text, link: ${propsVar}?.url ? { url: ${propsVar}.url } : undefined }, annotations: ${propsVar}.annotations }, ]` } else { objValue = ` type: '${propConfig._type}', ${propConfig._type}: props.${propConfig.varName},` } acc += ` if (props?.${propConfig.varName} !== undefined) { this.__data.properties['${propId}'] = {${objValue} } } ` return acc }, '') return content }