@@ -9,16 +9,26 @@ import {
99 serializePages ,
1010} from "@webstudio-is/sdk" ;
1111import * as projectApi from "@webstudio-is/project/index.server" ;
12+ import { getUserById , type User } from "./user.server" ;
13+
14+ export type PublishedProjectData = Data & {
15+ user : { email : User [ "email" ] } | undefined ;
16+ projectDomain : string ;
17+ projectTitle : string ;
18+ } ;
1219
1320const getPair = < Item extends { id : string } > ( item : Item ) : [ string , Item ] => [
1421 item . id ,
1522 item ,
1623] ;
1724
18- export const loadProductionCanvasData = async (
25+ type Project = NonNullable < Awaited < ReturnType < typeof projectApi . loadById > > > ;
26+
27+ const loadProductionCanvasDataAndProject = async (
1928 buildId : string ,
20- context : AppContext
21- ) : Promise < Data > => {
29+ context : AppContext ,
30+ project ?: Project
31+ ) : Promise < { data : Data ; project : Project } > => {
2232 const build = await loadBuildById ( context , buildId ) ;
2333
2434 if ( build === undefined ) {
@@ -31,7 +41,10 @@ export const loadProductionCanvasData = async (
3141 throw new Error ( "The project is not published" ) ;
3242 }
3343
34- const project = await projectApi . loadById ( build . projectId , context ) ;
44+ project = project ?? ( await projectApi . loadById ( build . projectId , context ) ) ;
45+ if ( project === null ) {
46+ throw new Error ( `Project "${ build . projectId } " not found` ) ;
47+ }
3548
3649 const currentProjectDomains = project . domainsVirtual ;
3750
@@ -77,28 +90,90 @@ export const loadProductionCanvasData = async (
7790 ) ;
7891
7992 return {
80- build : {
81- id : build . id ,
82- projectId : build . projectId ,
83- version : build . version ,
84- createdAt : build . createdAt ,
85- updatedAt : build . updatedAt ,
86- pages : serializePages ( build . pages ) ,
87- breakpoints : build . breakpoints . map ( getPair ) ,
88- styles : build . styles . map ( ( item ) => [ getStyleDeclKey ( item ) , item ] ) ,
89- styleSources : build . styleSources . map ( getPair ) ,
90- styleSourceSelections : build . styleSourceSelections . map ( ( item ) => [
91- item . instanceId ,
92- item ,
93- ] ) ,
94- props : build . props . map ( getPair ) ,
95- dataSources : build . dataSources . map ( getPair ) ,
96- resources : build . resources . map ( getPair ) ,
97- instances : build . instances . map ( getPair ) ,
98- deployment,
93+ data : {
94+ build : {
95+ id : build . id ,
96+ projectId : build . projectId ,
97+ version : build . version ,
98+ createdAt : build . createdAt ,
99+ updatedAt : build . updatedAt ,
100+ pages : serializePages ( build . pages ) ,
101+ breakpoints : build . breakpoints . map ( getPair ) ,
102+ styles : build . styles . map ( ( item ) => [ getStyleDeclKey ( item ) , item ] ) ,
103+ styleSources : build . styleSources . map ( getPair ) ,
104+ styleSourceSelections : build . styleSourceSelections . map ( ( item ) => [
105+ item . instanceId ,
106+ item ,
107+ ] ) ,
108+ props : build . props . map ( getPair ) ,
109+ dataSources : build . dataSources . map ( getPair ) ,
110+ resources : build . resources . map ( getPair ) ,
111+ instances : build . instances . map ( getPair ) ,
112+ deployment,
113+ } ,
114+ page,
115+ pages : getAllPages ( build . pages ) ,
116+ assets,
99117 } ,
100- page,
101- pages : getAllPages ( build . pages ) ,
102- assets,
118+ project,
119+ } ;
120+ } ;
121+
122+ const addProjectMetadata = async (
123+ data : Data ,
124+ project : Project ,
125+ context : AppContext
126+ ) : Promise < PublishedProjectData > => {
127+ const user =
128+ project . userId === null
129+ ? undefined
130+ : await getUserById ( context , project . userId ) ;
131+
132+ return {
133+ ...data ,
134+ user : user ? { email : user . email } : undefined ,
135+ projectDomain : project . domain ,
136+ projectTitle : project . title ,
103137 } ;
104138} ;
139+
140+ export const loadProductionCanvasData = async (
141+ buildId : string ,
142+ context : AppContext
143+ ) : Promise < Data > => {
144+ const { data } = await loadProductionCanvasDataAndProject ( buildId , context ) ;
145+ return data ;
146+ } ;
147+
148+ export const loadPublishedProjectDataByBuildId = async (
149+ buildId : string ,
150+ context : AppContext
151+ ) : Promise < PublishedProjectData > => {
152+ const { data, project } = await loadProductionCanvasDataAndProject (
153+ buildId ,
154+ context
155+ ) ;
156+ return await addProjectMetadata ( data , project , context ) ;
157+ } ;
158+
159+ export const loadPublishedProjectDataByProjectId = async (
160+ projectId : string ,
161+ context : AppContext
162+ ) : Promise < PublishedProjectData > => {
163+ const project = await projectApi . loadById ( projectId , context ) ;
164+ if ( project === null ) {
165+ throw new Error ( `Project "${ projectId } " not found` ) ;
166+ }
167+
168+ const buildId = project . latestBuildVirtual ?. buildId ;
169+ if ( buildId === undefined || buildId === null ) {
170+ throw new Error ( "The project is not published yet" ) ;
171+ }
172+
173+ const { data } = await loadProductionCanvasDataAndProject (
174+ buildId ,
175+ context ,
176+ project
177+ ) ;
178+ return await addProjectMetadata ( data , project , context ) ;
179+ } ;
0 commit comments