import { ProjectSyncMetadataModel } from "@plasmicapp/code-merger" ; import axios , { AxiosError } from "axios" ; import socketio from "socket.io-client" ; import { AuthConfig , CodeConfig , DEFAULT_HOST , ImagesConfig , StyleConfig , } from "./utils/config-utils" ; import { HandledError } from "./utils/error" ; import { Metadata } from "./utils/get-context" ; export class AppServerError extends Error { constructor ( message ) { super ( message ) ; } } export interface ComponentBundle { renderModule : string ; skeletonModule : string ; cssRules : string ; renderModuleFileName : string ; skeletonModuleFileName : string ; cssFileName : string ; componentName : string ; id : string ; scheme : string ; nameInIdToUuid : Array < [ string , string ] > ; isPage : boolean ; plumeType ? : string ; } export interface GlobalVariantBundle { id : string ; name : string ; contextModule : string ; contextFileName : string ; } export interface JsBundleTheme { themeFileName : string ; themeModule : string ; bundleName : string ; } export interface ProjectMetaBundle { projectId : string ; projectName : string ; cssFileName : string ; cssRules : string ; jsBundleThemes ? : JsBundleTheme [ ] ; } export interface IconBundle { id : string ; name : string ; module : string ; fileName : string ; } export interface ImageBundle { id : string ; name : string ; blob : string ; fileName : string ; } export interface ProjectVersionMeta { projectId : string ; projectApiToken : string ; version : string ; projectName : string ; componentIds : string [ ] ; dependencies : { [ projectId ] : string ; } ; indirect : boolean ; } export interface VersionResolution { projects : ProjectVersionMeta [ ] ; dependencies : ProjectVersionMeta [ ] ; conflicts : ProjectVersionMeta [ ] ; } export interface RequiredPackages { "@plasmicapp/loader" : string ; "@plasmicapp/cli" : string ; "@plasmicapp/react-web" : string ; "@plasmicapp/react-web-runtime" : string ; } export interface ProjectBundle { components : ComponentBundle [ ] ; codeComponentMetas : CodeComponentMeta [ ] ; projectConfig : ProjectMetaBundle ; globalVariants : GlobalVariantBundle [ ] ; usedTokens : StyleTokensMap ; iconAssets : IconBundle [ ] ; imageAssets : ImageBundle [ ] ; checksums : ChecksumBundle ; usedNpmPackages : string [ ] ; externalCssImports : string [ ] ; } export type ProjectMeta = Omit < ProjectBundle , "projectConfig" > ; export interface StyleConfigResponse { defaultStyleCssFileName : string ; defaultStyleCssRules : string ; } export interface StyleTokensMap { props : { name : string ; type : string ; value : string | number ; meta : { projectId : string ; id : string ; } ; } [ ] ; global : { meta : { source : "plasmic.app" ; } ; } ; } export interface ChecksumBundle { renderModuleChecksums : Array < [ string , string ] > ; cssRulesChecksums : Array < [ string , string ] > ; imageChecksums : Array < [ string , string ] > ; iconChecksums : Array < [ string , string ] > ; globalVariantChecksums : Array < [ string , string ] > ; projectCssChecksum : string ; } export interface CodeComponentMeta { id : string ; name : string ; importPath : string ; } export interface ProjectIconsResponse { version : string ; icons : IconBundle [ ] ; } export interface ProjectIdAndToken { projectId : string ; projectApiToken ? : string ; } export class PlasmicApi { constructor ( private auth ) { } async genStyleConfig ( styleOpts ? ) { const result = await this . post ( `${ this . codegenHost }/api/v1/code/style-config` , styleOpts ) ; return result . data as StyleConfigResponse ; } param projects param recursive async resolveSync ( projects , recursive ? ) { const resp = await this . post ( `${ this . codegenHost }/api/v1/code/resolve-sync` , { projects , recursive , } ) ; const versionResolution = resp . data as VersionResolution ; return { ... versionResolution } ; } async getCurrentUser ( ) { return await axios . get ( `${ this . studioHost }/api/v1/auth/self` , { headers : this . makeHeaders ( ) , } ) ; } async requiredPackages ( ) { const resp = await this . post ( `${ this . codegenHost }/api/v1/code/required-packages` ) ; return { ... resp . data } as RequiredPackages ; } param projectId param cliVersion param reactWebVersion param newCompScheme param existingCompScheme param componentIdOrNames param version async projectComponents ( projectId , opts ) { const result = await this . post ( `${ this . codegenHost }/api/v1/projects/${ projectId }/code/components` , { ... opts , } ) ; return result . data as ProjectBundle ; } async uploadBundle ( projectId , bundleName , bundleJs , css , metaJson , genModulePath , genCssPaths , pkgVersion , extraPropMetaJson , themeProviderWrapper , themeModule ) { const result = await this . post ( `${ this . codegenHost }/api/v1/projects/${ projectId }/jsbundle/upload` , { projectId , bundleName , bundleJs , css , metaJson , genModulePath , genCssPaths , pkgVersion , extraPropMetaJson , themeProviderWrapper , themeModule , } ) ; return result . data as StyleTokensMap ; } async projectStyleTokens ( projectId , versionRange ? ) { const result = await this . post ( `${ this . codegenHost }/api/v1/projects/${ projectId }/code/tokens` , { versionRange } ) ; return result . data as StyleTokensMap ; } async projectIcons ( projectId , versionRange ? , iconIds ? ) { const result = await this . post ( `${ this . codegenHost }/api/v1/projects/${ projectId }/code/icons` , { versionRange , iconIds } ) ; return result . data as ProjectIconsResponse ; } async projectSyncMetadata ( projectId , revision , rethrowAppError ) { const result = await this . post ( `${ this . codegenHost }/api/v1/projects/${ projectId }/code/project-sync-metadata` , { revision } , rethrowAppError ) ; return ProjectSyncMetadataModel . fromJson ( result . data ) ; } connectSocket ( ) { const socket = socketio . connect ( this . studioHost , { path : `/api/v1/socket` , transportOptions : { polling : { extraHeaders : this . makeHeaders ( ) , } , } , } ) ; return socket ; } private async post ( url , data ? , rethrowAppError ? ) { try { return await axios . post ( url , { projectIdsAndTokens : this . projectIdsAndTokens , ... data } , { headers : this . makeHeaders ( ) , } ) ; } catch ( e ) { const error = e as AxiosError ; const errorMsg = this . makeErrorMessage ( error ) ; if ( rethrowAppError ) { throw new AppServerError ( errorMsg ) ; } if ( ! errorMsg ) { throw e ; } throw new HandledError ( errorMsg ) ; } } private makeErrorMessage ( error ) { const response = error . response ; if ( ! response ) { return undefined ; } if ( response . status === 403 ) { return `Incorrect Plasmic credentials; please check your .plasmic.auth file or your project API tokens.` ; } if ( response . data ?. error ?. message ) { return response . data . error . message ; } else if ( response . data ) { return `Error: request failed with status code ${ response . status }. The response is
  ${ response . data }` ; } else { return undefined ; } } private makeHeaders ( ) { const headers = { "x-plasmic-api-user" : this . auth . user , "x-plasmic-api-token" : this . auth . token , } ; if ( this . auth . basicAuthUser && this . auth . basicAuthPassword ) { const authString = Buffer . from ( `${ this . auth . basicAuthUser }:${ this . auth . basicAuthPassword }` ) . toString ( "base64" ) ; headers [ "Authorization" ] = `Basic ${ authString }` ; } return headers ; } private projectIdsAndTokens ? : ProjectIdAndToken [ ] ; attachProjectIdsAndTokens ( idsAndTokens ) { this . projectIdsAndTokens = idsAndTokens ; } private get studioHost ( ) { return this . auth . host ; } private get codegenHost ( ) { if ( ! this . auth . host || this . auth . host === DEFAULT_HOST ) { return "https://codegen.plasmic.app" ; } else { return this . auth . host ; } } }