1- import { Result } from 'true-myth'
1+ import { Result } from 'true-myth'
22
3- import { BuildpackBody , BuildpackRegistryApi as Api , Category , HeaderOptions , ReadmeBody , Response , RevisionBody , RevisionStatus } from './buildpack-registry-api'
3+ import { BuildpackBody , BuildpackRegistryApi as Api , Category , HeaderOptions , ReadmeBody , Response , RevisionBody , RevisionStatus } from './buildpack-registry-api'
44
5- export { BuildpackBody , Category , ReadmeBody , RevisionBody , RevisionStatus }
5+ import { Headers } from 'node-fetch'
6+
7+ export { BuildpackBody , Category , ReadmeBody , RevisionBody , RevisionStatus }
68
79const BUILDPACK_FORMATTING_MESSAGE = "To specify a buildpack, please format it like the following: namespace/name (e.g. heroku/ruby). Also names can only contain letters, numbers, '_', and '-'."
810
@@ -58,15 +60,41 @@ export class BuildpackRegistry {
5860 }
5961 }
6062
63+ async list ( path : string ) : Promise < Result < Array < any > , ResponseError > > {
64+ let page = await this . api . get ( path ) ;
65+ let items = [ ] ;
66+ if ( page . status === 200 || page . status === 206 ) {
67+ items = await page . json ( ) ;
68+ }
69+ while ( page . status === 206 ) {
70+ let nextRange = page . headers . get ( 'Next-Range' )
71+ if ( typeof nextRange !== "string" ) {
72+ break ;
73+ }
74+ page = await this . api . get ( path , new Headers ( { 'Accept-Range' : nextRange } ) ) ;
75+ if ( page . status === 200 || page . status === 206 ) {
76+ items = [ ...items , ...await page . json ( ) ] ;
77+ }
78+ }
79+ if ( page . status !== 200 ) {
80+ return Result . err ( {
81+ status : page . status ,
82+ path,
83+ description : await page . text ( )
84+ } ) ;
85+ }
86+ return Result . ok ( items ) ;
87+ }
88+
6189 async publish ( buildpack : string , ref : string , token : string , secondFactor ?: string ) : Promise < Result < RevisionBody , ResponseError > > {
62- let options : HeaderOptions = { token}
90+ let options : HeaderOptions = { token }
6391 if ( secondFactor !== undefined ) {
6492 options . secondFactor = secondFactor
6593 }
6694 let path = `/buildpacks/${ encodeURIComponent ( buildpack ) } /revisions`
6795 let response = await this . api . post (
6896 path ,
69- { ref} ,
97+ { ref } ,
7098 this . api . headers ( options ) )
7199
72100 if ( response . status === 200 ) {
@@ -81,7 +109,7 @@ export class BuildpackRegistry {
81109 }
82110
83111 async rollback ( buildpack : string , token : string , secondFactor ?: string ) : Promise < Result < RevisionBody , ResponseError > > {
84- let options : HeaderOptions = { token}
112+ let options : HeaderOptions = { token }
85113 if ( secondFactor !== undefined ) {
86114 options . secondFactor = secondFactor
87115 }
@@ -123,16 +151,7 @@ export class BuildpackRegistry {
123151 }
124152
125153 let path = `/buildpacks${ queryString } `
126- let response = await this . api . get ( path )
127- if ( response . status === 200 ) {
128- return Result . ok ( await response . json ( ) )
129- } else {
130- return Result . err ( {
131- status : response . status ,
132- path,
133- description : await response . text ( ) ,
134- } )
135- }
154+ return this . list ( path ) ;
136155 }
137156
138157 async info ( buildpack : string ) : Promise < Result < InfoData , ResponseError > > {
@@ -189,14 +208,18 @@ export class BuildpackRegistry {
189208 }
190209
191210 if ( readme . content ) {
192- data . readme = `\n${ Buffer . from ( readme . content , readme . encoding ) . toString ( ) } `
211+ let encoding : BufferEncoding = 'utf8' ;
212+ if ( readme . encoding && [ 'ascii' , 'utf16le' , 'latin1' , 'base64' , 'base64url' ] . includes ( readme . encoding ) ) {
213+ encoding = readme . encoding as BufferEncoding ;
214+ }
215+ data . readme = `\n${ Buffer . from ( readme . content , encoding ) . toString ( ) } `
193216 }
194217
195218 return Result . ok ( data )
196219 }
197220
198221 async archive ( buildpack : string , token : string , secondFactor ?: string ) : Promise < Result < BuildpackBody , ResponseError > > {
199- let options : HeaderOptions = { token}
222+ let options : HeaderOptions = { token }
200223 if ( secondFactor !== undefined ) {
201224 options . secondFactor = secondFactor
202225 }
@@ -233,17 +256,7 @@ export class BuildpackRegistry {
233256
234257 async listVersions ( buildpack : string ) : Promise < Result < RevisionBody [ ] , ResponseError > > {
235258 let path = `/buildpacks/${ encodeURIComponent ( buildpack ) } /revisions`
236- let response = await this . api . get ( path )
237-
238- if ( response . status === 200 ) {
239- return Result . ok ( await response . json ( ) )
240- } else {
241- return Result . err ( {
242- status : response . status ,
243- path,
244- description : await response . text ( )
245- } )
246- }
259+ return await this . list ( path )
247260 }
248261
249262 async delay ( ms : number ) {
0 commit comments