1
1
import { color } from '@heroku-cli/color'
2
2
import { flags } from '@heroku-cli/command'
3
3
import { ux , Args } from '@oclif/core'
4
+ import axios from 'axios'
4
5
import fs from 'fs'
5
6
import path from 'path'
6
- import { gzipSync } from 'zlib'
7
7
import Command from '../../lib/base'
8
8
import * as AppLink from '../../lib/applink/types'
9
+ import AdmZip from 'adm-zip'
9
10
10
11
export default class Publish extends Command {
11
12
static description = 'publish an app\'s API specification to an authenticated Salesforce org'
@@ -25,6 +26,12 @@ export default class Publish extends Command {
25
26
api_spec_file_dir : Args . file ( { required : true , description : 'path to OpenAPI 3.x spec file (JSON or YAML format)' } ) ,
26
27
}
27
28
29
+ protected createZipArchive = async ( files : AppLink . FileEntry [ ] ) => {
30
+ const zipArchive = new AdmZip ( )
31
+ files . forEach ( file => zipArchive . addFile ( file . name , file . content ) )
32
+ return zipArchive . toBuffer ( )
33
+ }
34
+
28
35
public async run ( ) : Promise < void > {
29
36
const { flags, args} = await this . parse ( Publish )
30
37
const { app, addon, 'client-name' : clientName , 'connection-name' : connectionName , 'authorization-connected-app-name' : authorizationConnectedAppName , 'authorization-permission-set-name' : authorizationPermissionSetName , 'metadata-dir' : metadataDir } = flags
@@ -82,32 +89,48 @@ export default class Publish extends Command {
82
89
}
83
90
}
84
91
85
- const filesForJson = files . map ( file => ( {
86
- name : file . name ,
87
- content : file . content . toString ( 'base64' ) ,
92
+ const compressedContent = await this . createZipArchive ( files )
93
+ const appRequestContent = {
94
+ client_name : clientName ,
95
+ authorization_connected_app_name : authorizationConnectedAppName ,
96
+ authorization_permission_set_name : authorizationPermissionSetName ,
97
+ }
98
+ const formData = new FormData ( )
99
+ formData . append ( 'metadata' , new Blob ( [
100
+ compressedContent ,
101
+ ] , {
102
+ type : 'application/zip' ,
103
+ }
104
+ ) )
105
+ formData . append ( 'app_request' , new Blob ( [
106
+ JSON . stringify ( appRequestContent ) ,
107
+ ] , {
108
+ type : 'application/json' ,
88
109
} ) )
89
110
90
- const compressedContent = gzipSync ( JSON . stringify ( filesForJson ) )
91
- const binaryMetadataZip = compressedContent . toString ( 'base64' )
92
-
93
111
await this . configureAppLinkClient ( app , addon )
94
112
95
- ux . action . start ( `Publishing ${ color . app ( app ) } to ${ color . yellow ( connectionName ) } as ${ color . yellow ( clientName ) } ` )
96
-
97
- await this . applinkClient . post < AppLink . AppPublish > (
98
- `/addons/${ this . addonId } /connections/salesforce/${ connectionName } /apps` ,
99
- {
100
- headers : { authorization : `Bearer ${ this . _applinkToken } ` } ,
101
- body : {
102
- app_request : {
103
- client_name : clientName ,
104
- authorization_connected_app_name : authorizationConnectedAppName ,
105
- authorization_permission_set_name : authorizationPermissionSetName ,
106
- } ,
107
- metadata_zip : binaryMetadataZip ,
108
- } ,
109
- retryAuth : false ,
110
- } )
113
+ const publishURL = `https://${ this . _applink . defaults . host } /addons/${ this . addonId } /connections/salesforce/${ connectionName } /apps`
114
+ const headers = this . _applink . defaults . headers || { }
115
+
116
+ ux . action . start ( `Publishing ${ color . app ( app ) } to ${ color . yellow ( connectionName ) } as ${ color . yellow ( clientName ) } via ${ publishURL } ` )
117
+
118
+ await axios . post ( publishURL , formData , {
119
+ headers : {
120
+ accept : 'application/json' ,
121
+ 'Content-Type' : 'multipart/form-data' ,
122
+ Authorization : `Bearer ${ this . _applinkToken } ` ,
123
+ 'x-addon-sso' : headers [ 'x-addon-sso' ] ,
124
+ 'x-app-uuid' : headers [ 'x-app-uuid' ] ,
125
+ 'User-Agent' : headers [ 'user-agent' ] ,
126
+ } ,
127
+ } ) . catch ( error => {
128
+ if ( error . response . data && error . response . data . message ) {
129
+ ux . error ( error . response . data . message , { exit : 1 } )
130
+ } else {
131
+ throw error
132
+ }
133
+ } )
111
134
112
135
ux . action . stop ( )
113
136
}
0 commit comments