import { BaseAPIClient , StorageDriver , Container , GlobalJSONContainerStorage , ContainerOptions , VERSION , _PresignUploadRequest , } from "@skygear/core" ; import { Readable } from "stream" ; export * from "@skygear/core" ; import { type , release , hostname } from "os" ; import nodeFetch , { Request , Headers } from "node-fetch" ; public export class NodeAPIClient extends BaseAPIClient { fetchFunction = nodeFetch as any ; requestClass = Request as any ; userAgent = `skygear-node-client/${ VERSION } (Skygear; ${ type ( ) } ${ release ( ) })` ; } public export class MemoryStorageDriver implements StorageDriver { backingStore : { [ key ] : string ; } ; constructor ( ) { this . backingStore = { } ; } async get ( key ) { const value = this . backingStore [ key ] ; if ( value != null ) { return value ; } return null ; } async set ( key , value ) { this . backingStore [ key ] = value ; } async del ( key ) { delete this . backingStore [ key ] ; } } remarks public export async function getDeviceName ( ) { return hostname ( ) ; } async function uploadData ( method , url , headers , data ) { const fetchHeaders = new Headers ( ) ; for ( const header of headers ) { fetchHeaders . set ( header . name , header . value ) ; } const init = { method , headers : fetchHeaders , mode : "cors" , body : data } ; const response = await nodeFetch ( url , init ) ; return response . status ; } public export interface UploadAssetOptions { /**
     * The asset name prefix.
     */ prefix ? : string ; /**
     * The access control type of asset.
     */ access ? : "public" | "private" ; /**
     * Additional HTTP headers to be returned with the asset.
     */ headers ? : { [ name ] : string ; } ; /**
     * Asset size in bytes.
     */ size ? : number ; } public export class NodeAssetContainer < T extends NodeAPIClient > { parent : NodeContainer < T > ; constructor ( parent ) { this . parent = parent ; } param data param options returns async upload ( data , options ? ) { const presignRequest = { } ; if ( options != null ) { presignRequest . prefix = options . prefix ; presignRequest . access = options . access ; if ( options . headers != null ) { presignRequest . headers = { ... options . headers } ; } } const presignRequestHeaders = presignRequest . headers || { } ; let hasContentLength = false ; for ( const key of Object . keys ( presignRequestHeaders ) ) { const headerName = key . toLowerCase ( ) ; switch ( headerName ) { case "content-length" : hasContentLength = true ; break ; default : break ; } } if ( ! hasContentLength ) { if ( data instanceof Buffer ) { presignRequestHeaders [ "content-length" ] = String ( data . length ) ; } else if ( options != null && typeof options . size === "number" ) { presignRequestHeaders [ "content-length" ] = String ( options . size ) ; } else { throw new Error ( "must provide `size' when data is Readable" ) ; } } presignRequest . headers = presignRequestHeaders ; const { asset_name , url , method , headers , } = await this . parent . apiClient . _presignUpload ( presignRequest ) ; const status = await uploadData ( method , url , headers , data ) ; if ( status < 200 || status > 299 ) { throw new Error ( "Unexpected upload status: " + status ) ; } return asset_name ; } } public export interface ConfigureOptions { /**
     * The OAuth client ID.
     */ clientID : string ; /**
     * The app endpoint.
     */ appEndpoint : string ; /**
     * The Skygear Auth endpoint. If it is omitted, it is derived by pre-pending `accounts.` to the domain of the app endpoint.
     */ authEndpoint ? : string ; /**
     * The Skygear asset endpoint. If it is omitted, it is derived by pre-pending `assets.` to the domain of the app endpoint.
     */ assetEndpoint ? : string ; } public export class NodeContainer < T extends NodeAPIClient > extends Container < T > { asset : NodeAssetContainer < T > ; constructor ( options ? ) { const o = { ... options , apiClient : ( options && options . apiClient ) || new NodeAPIClient ( ) , storage : ( options && options . storage ) || new GlobalJSONContainerStorage ( new MemoryStorageDriver ( ) ) } as ContainerOptions < T > ; super ( o ) ; this . asset = new NodeAssetContainer ( this ) ; } param options async configure ( options ) { await this . _configure ( { apiKey : options . clientID , endpoint : options . appEndpoint , authEndpoint : options . authEndpoint , assetEndpoint : options . assetEndpoint } ) ; } } remarks public const defaultContainer = new NodeContainer ( ) ; export default defaultContainer ;