a tool for shared writing and social publishing
1"use server"; 2 3import { drizzle } from "drizzle-orm/node-postgres"; 4import { 5 entities, 6 identities, 7 permission_tokens, 8 permission_token_rights, 9 entity_sets, 10 facts, 11 permission_token_on_homepage, 12 email_auth_tokens, 13} from "drizzle/schema"; 14import { redirect } from "next/navigation"; 15import postgres from "postgres"; 16import { v7 } from "uuid"; 17import { sql, eq, and } from "drizzle-orm"; 18import { cookies } from "next/headers"; 19import { pool } from "supabase/pool"; 20 21export async function createNewLeaflet({ 22 pageType, 23 redirectUser, 24 firstBlockType, 25}: { 26 pageType: "canvas" | "doc"; 27 redirectUser: boolean; 28 firstBlockType?: "h1" | "text"; 29}) { 30 let auth_token = (await cookies()).get("auth_token")?.value; 31 const client = await pool.connect(); 32 const db = drizzle(client); 33 let { permissionToken } = await db.transaction(async (tx) => { 34 // Create a new entity set 35 let [entity_set] = await tx.insert(entity_sets).values({}).returning(); 36 // Create a root-entity 37 38 let [root_entity] = await tx 39 .insert(entities) 40 // And add it to that permission set 41 .values({ set: entity_set.id, id: v7() }) 42 .returning(); 43 let [first_page] = await tx 44 .insert(entities) 45 // And add it to that permission set 46 .values({ set: entity_set.id, id: v7() }) 47 .returning(); 48 //Create a new permission token 49 let [permissionToken] = await tx 50 .insert(permission_tokens) 51 .values({ root_entity: root_entity.id }) 52 .returning(); 53 //and give it all the permission on that entity set 54 let [rights] = await tx 55 .insert(permission_token_rights) 56 .values({ 57 token: permissionToken.id, 58 entity_set: entity_set.id, 59 read: true, 60 write: true, 61 create_token: true, 62 change_entity_set: true, 63 }) 64 .returning(); 65 66 let [blockEntity] = await tx 67 .insert(entities) 68 // And add it to that permission set 69 .values({ set: entity_set.id, id: v7() }) 70 .returning(); 71 await tx.insert(facts).values([ 72 { 73 id: v7(), 74 entity: root_entity.id, 75 attribute: "root/page", 76 data: sql`${{ type: "ordered-reference", value: first_page.id, position: "a0" }}`, 77 }, 78 //Set theme/page-leaflet-watermark to true by default for new leaflets 79 { 80 id: v7(), 81 entity: root_entity.id, 82 attribute: "theme/page-leaflet-watermark", 83 data: sql`${{ type: "boolean", value: true }}`, 84 }, 85 ]); 86 87 if (pageType === "canvas") { 88 await tx.insert(facts).values([ 89 { 90 id: v7(), 91 entity: first_page.id, 92 attribute: "page/type", 93 data: sql`${{ type: "page-type-union", value: "canvas" }}`, 94 }, 95 { 96 id: v7(), 97 entity: first_page.id, 98 attribute: "canvas/block", 99 data: sql`${{ type: "spatial-reference", value: blockEntity.id, position: { x: 8, y: 12 } }}::jsonb`, 100 }, 101 { 102 id: v7(), 103 entity: blockEntity.id, 104 attribute: "block/type", 105 data: sql`${{ type: "block-type-union", value: "text" }}::jsonb`, 106 }, 107 ]); 108 } else { 109 await tx.insert(facts).values([ 110 { 111 id: v7(), 112 entity: first_page.id, 113 attribute: "card/block", 114 data: sql`${{ type: "ordered-reference", value: blockEntity.id, position: "a0" }}::jsonb`, 115 }, 116 ...(firstBlockType === "text" 117 ? [ 118 { 119 id: v7(), 120 entity: blockEntity.id, 121 attribute: "block/type", 122 data: sql`${{ type: "block-type-union", value: "text" }}::jsonb`, 123 }, 124 ] 125 : [ 126 { 127 id: v7(), 128 entity: blockEntity.id, 129 attribute: "block/type", 130 data: sql`${{ type: "block-type-union", value: "heading" }}::jsonb`, 131 }, 132 { 133 id: v7(), 134 entity: blockEntity.id, 135 attribute: "block/heading-level", 136 data: sql`${{ type: "number", value: 1 }}::jsonb`, 137 }, 138 ]), 139 ]); 140 } 141 if (auth_token) { 142 await tx.execute(sql` 143 WITH auth_token AS ( 144 SELECT identities.id as identity_id 145 FROM email_auth_tokens 146 LEFT JOIN identities ON email_auth_tokens.identity = identities.id 147 WHERE email_auth_tokens.id = ${auth_token} 148 AND email_auth_tokens.confirmed = true 149 AND identities.id IS NOT NULL 150 ) 151 INSERT INTO permission_token_on_homepage (token, identity) 152 SELECT ${permissionToken.id}, identity_id 153 FROM auth_token 154 `); 155 } 156 157 return { permissionToken, rights, root_entity, entity_set }; 158 }); 159 160 client.release(); 161 if (redirectUser) redirect(`/${permissionToken.id}?focusFirstBlock`); 162 return permissionToken.id; 163}