UNPKG

@mikemajara/notion-cms

Version:

A TypeScript library for using Notion as a headless CMS

58 lines (54 loc) 11 kB
'use strict';var client=require('@notionhq/client'),g=require('fs'),h=require('path'),tsMorph=require('ts-morph');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var g__namespace=/*#__PURE__*/_interopNamespace(g);var h__namespace=/*#__PURE__*/_interopNamespace(h);function N(t){return /[^a-zA-Z0-9_$]/.test(t)?`"${t}"`:t}var j=(t,e)=>{switch(t){case "title":case "rich_text":case "url":case "email":case "phone_number":return "string";case "number":return "number";case "select":return e&&"select"in e&&e.select&&"options"in e.select&&Array.isArray(e.select.options)&&e.select.options.length>0?e.select.options.map(a=>`"${a.name}"`).join(" | "):"string";case "multi_select":return e&&"multi_select"in e&&e.multi_select&&"options"in e.multi_select&&Array.isArray(e.multi_select.options)&&e.multi_select.options.length>0?`Array<${e.multi_select.options.map(l=>`"${l.name}"`).join(" | ")}>`:"string[]";case "date":return "Date";case "people":return "string[]";case "files":return "{ name: string; url: string; }[]";case "checkbox":return "boolean";case "formula":return "any";case "relation":return "string[]";case "rollup":return "any";case "created_time":case "last_edited_time":return "string";case "created_by":case "last_edited_by":return "{ id: string; name: string | null; avatar_url: string | null; }";default:return "any"}};function w(t){let e=t.replace(/[^\w\s]/g,"").replace(/\s+(.)/g,(a,l)=>l.toUpperCase()).replace(/\s/g,"");return "Record"+e.charAt(0).toUpperCase()+e.slice(1)}function A(t){return `notion-types-${t.toLowerCase().replace(/[^\w\s]/g,"").replace(/\s+/g,"-")}.ts`}async function U(t,e,a){let y=await new client.Client({auth:a}).databases.retrieve({database_id:t}),d=y.properties,i="NotionDatabase",n=y;if(n.title&&Array.isArray(n.title)&&n.title.length>0){let p=n.title[0].plain_text;p&&(i=p);}if(i==="NotionDatabase"){i=t.replace(/-/g,"").substring(0,12);let p=Object.keys(d).find(f=>d[f].type==="title");p&&(i=p);}let b=w(i),m=A(i);g__namespace.mkdirSync(e,{recursive:true});let u=h__namespace.join(e,m),r=new tsMorph.Project().createSourceFile(u,"",{overwrite:true});F(r,d,b,i,t),await r.save(),P(e,m);}function P(t,e){let a=h__namespace.join(t,"index.ts");g__namespace.existsSync(a)||g__namespace.writeFileSync(a,`// Auto-generated index file for Notion CMS types // Export database-specific types `);let l=g__namespace.readFileSync(a,"utf8"),y=`import './${e.replace(".ts","")}';`;l.includes(y)||(l+=`${y} `,g__namespace.writeFileSync(a,l));}function F(t,e,a,l,y){try{t.addStatements(`/** * THIS FILE IS AUTO-GENERATED BY NOTION-CMS * DO NOT EDIT DIRECTLY - YOUR CHANGES WILL BE OVERWRITTEN * v0.1.3 * Generated for database: ${l} */`),t.addImportDeclaration({moduleSpecifier:"@mikemajara/notion-cms",namedImports:["DatabaseRecord","NotionCMS","QueryBuilder","DatabaseFieldMetadata"]}),t.addImportDeclaration({moduleSpecifier:"@notionhq/client/build/src/api-endpoints",namedImports:["PageObjectResponse"]});let d=s=>{switch(s){case "title":return "{ content: string; annotations: any; href: string | null; link?: { url: string } | null }[]";case "rich_text":return "{ content: string; annotations: any; href: string | null; link?: { url: string } | null }[]";case "number":return "number";case "select":return "{ id: string; name: string; color: string } | null";case "multi_select":return "{ id: string; name: string; color: string }[]";case "date":return "{ start: string; end: string | null; time_zone: string | null; parsedStart: Date | null; parsedEnd: Date | null } | null";case "people":return "{ id: string; name: string | null; avatar_url: string | null; object: string; type: string; email?: string }[]";case "files":return "{ name: string; type: string; external?: { url: string }; file?: { url: string; expiry_time: string } }[]";case "checkbox":return "boolean";case "url":return "string";case "email":return "string";case "phone_number":return "string";case "formula":return "{ type: string; value: any }";case "relation":return "{ id: string }[]";case "rollup":return "{ type: string; function: string; array?: any[]; number?: number; date?: any }";case "created_time":return "{ timestamp: string; date: Date }";case "created_by":case "last_edited_by":return "{ id: string; name: string | null; avatar_url: string | null; object: string; type: string; email?: string }";case "last_edited_time":return "{ timestamp: string; date: Date }";case "status":return "{ id: string; name: string; color: string } | null";case "unique_id":return "{ prefix: string | null; number: number }";default:return "any"}},i=[];i.push(`export const ${a}FieldTypes = {`),i.push(' "id": { type: "unique_id" },');for(let[s,r]of Object.entries(e))if(r.type==="select"||r.type==="multi_select"){let p=(r.type==="select"?r.select.options:r.multi_select.options).map(f=>`"${f.name}"`).join(", ");i.push(` "${s}": { type: "${r.type}", options: [${p}] as const },`);}else i.push(` "${s}": { type: "${r.type}" },`);i.push("} as const satisfies DatabaseFieldMetadata;"),t.addStatements(i.join(` `));let n=a,b=`${n}Advanced`,m=`${n}Raw`;t.addInterface({name:b,properties:[{name:"id",type:"string"},...Object.entries(e).map(([s,r])=>({name:N(s),type:d(r.type)}))],isExported:!0}),t.addInterface({name:m,properties:[{name:"id",type:"string"},{name:"properties",type:"Record<string, any>"}],isExported:!0}),t.addInterface({name:n,extends:["DatabaseRecord"],properties:[{name:"id",type:"string"},...Object.entries(e).map(([s,r])=>({name:N(s),type:j(r.type,r)}))],isExported:!0});let u=l.replace(/[^\w\s]/g,"").replace(/\s+(.)/g,(s,r)=>r.toUpperCase()).replace(/\s/g,"").replace(/^./,s=>s.toLowerCase());t.addStatements(` // Extend DatabaseRegistry interface with this database declare module "@mikemajara/notion-cms" { interface DatabaseRegistry { ${u}: { record: ${a}; recordAdvanced: ${b}; recordRaw: PageObjectResponse; fields: typeof ${a}FieldTypes; }; } } // Add database configuration to the registry NotionCMS.prototype.databases["${u}"] = { id: process.env.NOTION_CMS_${u.toUpperCase()}_DATABASE_ID || "${y}", fields: ${a}FieldTypes, }; `);}catch(d){console.error("Error generating database-specific types:",d);}}async function L(t,e,a){let l=new client.Client({auth:a}),d=h__namespace.join(e,"notion-types-combined.ts"),n=new tsMorph.Project().createSourceFile(d,"",{overwrite:true});n.addStatements(`/** * THIS FILE IS AUTO-GENERATED BY NOTION-CMS * DO NOT EDIT DIRECTLY - YOUR CHANGES WILL BE OVERWRITTEN * * Generated for multiple databases: ${t.join(", ")} */`),n.addImportDeclaration({moduleSpecifier:"@mikemajara/notion-cms",namedImports:["DatabaseRecord","NotionCMS","DatabaseFieldMetadata"]});let b=[];for(let m of t)try{console.log(`Processing database: ${m}`);let u=await l.databases.retrieve({database_id:m}),s=u.properties,r=`Database${m.substring(0,8)}`,p=u;if(p.title&&Array.isArray(p.title)&&p.title.length>0){let o=p.title[0].plain_text;o&&(r=o);}let f=w(r),_=`query${r.replace(/[^\w\s]/g,"").replace(/\s+(.)/g,(o,c)=>c.toUpperCase()).replace(/\s/g,"").replace(/^./,o=>o.toUpperCase())}`,T=1,I=_;for(;b.includes(_);)_=`${I}${T}`,T++;b.push(_),n.addStatements(` // ============================================================================ // ${r} Database Types // ============================================================================ `),n.addStatements(`export const ${f}FieldTypes = {`),n.addStatements(' "id": { type: "string" },');for(let[o,c]of Object.entries(s))if(c.type==="select"||c.type==="multi_select"){let v=(c.type==="select"?c.select.options:c.multi_select.options).map(O=>`"${O.name}"`).join(", ");n.addStatements(` "${o}": { type: "${c.type}", options: [${v}] as const },`);}else n.addStatements(` "${o}": { type: "${c.type}" },`);n.addStatements("} as const satisfies DatabaseFieldMetadata;");let R=o=>{switch(o){case "title":return "{ content: string; annotations: any; href: string | null; link?: { url: string } | null }[]";case "rich_text":return "{ content: string; annotations: any; href: string | null; link?: { url: string } | null }[]";case "number":return "number";case "select":return "{ id: string; name: string; color: string } | null";case "multi_select":return "{ id: string; name: string; color: string }[]";case "date":return "{ start: string; end: string | null; time_zone: string | null; parsedStart: Date | null; parsedEnd: Date | null } | null";case "people":return "{ id: string; name: string | null; avatar_url: string | null; object: string; type: string; email?: string }[]";case "files":return "{ name: string; type: string; external?: { url: string }; file?: { url: string; expiry_time: string } }[]";case "checkbox":return "boolean";case "url":return "string";case "email":return "string";case "phone_number":return "string";case "formula":return "{ type: string; value: any }";case "relation":return "{ id: string }[]";case "rollup":return "{ type: string; function: string; array?: any[]; number?: number; date?: any }";case "created_time":return "{ timestamp: string; date: Date }";case "created_by":case "last_edited_by":return "{ id: string; name: string | null; avatar_url: string | null; object: string; type: string; email?: string }";case "last_edited_time":return "{ timestamp: string; date: Date }";case "status":return "{ id: string; name: string; color: string } | null";case "unique_id":return "{ prefix: string | null; number: number }";default:return "any"}},S=f,$=`${S}Advanced`,D=`${S}Raw`;n.addInterface({name:$,properties:[{name:"id",type:"string"},...Object.entries(s).map(([o,c])=>({name:N(o),type:R(c.type)}))],isExported:!0}),n.addInterface({name:D,properties:[{name:"id",type:"string"},{name:"properties",type:"Record<string, any>"}],isExported:!0}),n.addInterface({name:S,extends:["DatabaseRecord"],properties:[{name:"id",type:"string"},...Object.entries(s).map(([o,c])=>({name:N(o),type:j(c.type,c)})),{name:"advanced",type:$},{name:"raw",type:D}],isExported:!0});}catch(u){console.error(`Error processing database ${m}:`,u);}n.addStatements(` // ============================================================================ // NotionCMS Extension Methods // ============================================================================ // Extend DatabaseRegistry only; no instance helper methods are generated in combined mode /* eslint-disable */ declare module "@mikemajara/notion-cms" { interface NotionCMS {}`),n.addStatements(` // ============================================================================ // Method Implementations // ============================================================================ // No instance helper implementations are emitted in combined mode. `),await n.save(),console.log(`Generated combined types file: ${d}`);}exports.a=U;exports.b=L;