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}