chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import axiosRetry from 'axios-retry'
|
||||
import * as common from '../common'
|
||||
import * as gen from '../gen/files'
|
||||
import * as types from '../types'
|
||||
import * as uploadFile from './upload-file'
|
||||
|
||||
type IClient = common.types.Simplify<
|
||||
gen.Client & {
|
||||
uploadFile: (input: uploadFile.UploadFileInput) => Promise<uploadFile.UploadFileOutput>
|
||||
}
|
||||
>
|
||||
|
||||
export type Operation = common.types.Operation<IClient>
|
||||
export type ClientInputs = common.types.Inputs<IClient>
|
||||
export type ClientOutputs = common.types.Outputs<IClient>
|
||||
|
||||
export type ClientProps = common.types.CommonClientProps & {
|
||||
token: string
|
||||
botId: string
|
||||
integrationId?: string
|
||||
integrationAlias?: string
|
||||
}
|
||||
|
||||
export class Client extends gen.Client implements IClient {
|
||||
public readonly config: Readonly<types.ClientConfig>
|
||||
|
||||
public constructor(clientProps: ClientProps) {
|
||||
const clientConfig = common.config.getClientConfig(clientProps)
|
||||
const axiosInstance = common.axios.createAxiosInstance(clientConfig)
|
||||
|
||||
super(axiosInstance, {
|
||||
toApiError: common.errors.toApiError,
|
||||
})
|
||||
|
||||
if (clientProps.retry) {
|
||||
axiosRetry(axiosInstance, clientProps.retry)
|
||||
}
|
||||
|
||||
this.config = clientConfig
|
||||
}
|
||||
|
||||
public get list() {
|
||||
type ListInputs = common.types.ListInputs<IClient>
|
||||
return {
|
||||
files: (props: ListInputs['listFiles']) =>
|
||||
new common.listing.AsyncCollection(({ nextToken }) =>
|
||||
this.listFiles({ nextToken, ...props }).then((r) => ({ ...r, items: r.files }))
|
||||
),
|
||||
filePassages: (props: ListInputs['listFilePassages']) =>
|
||||
new common.listing.AsyncCollection(({ nextToken }) =>
|
||||
this.listFilePassages({ nextToken, ...props }).then((r) => ({ ...r, items: r.passages }))
|
||||
),
|
||||
fileTags: (props: ListInputs['listFileTags']) =>
|
||||
new common.listing.AsyncCollection(({ nextToken }) =>
|
||||
this.listFileTags({ nextToken, ...props }).then((r) => ({ ...r, items: r.tags }))
|
||||
),
|
||||
fileTagValues: (props: ListInputs['listFileTagValues']) =>
|
||||
new common.listing.AsyncCollection(({ nextToken }) =>
|
||||
this.listFileTagValues({ nextToken, ...props }).then((r) => ({ ...r, items: r.values }))
|
||||
),
|
||||
knowledgeBases: (props: ListInputs['listKnowledgeBases']) =>
|
||||
new common.listing.AsyncCollection(({ nextToken }) =>
|
||||
this.listKnowledgeBases({ nextToken, ...props }).then((r) => ({ ...r, items: r.knowledgeBases }))
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create/update and upload a file in a single step. Returns an object containing the file metadata and the URL to retrieve the file.
|
||||
*/
|
||||
public async uploadFile(input: uploadFile.UploadFileInput): Promise<uploadFile.UploadFileOutput> {
|
||||
return await uploadFile.upload(this, input)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import axios, { AxiosError } from 'axios'
|
||||
import * as common from '../common'
|
||||
import * as errors from '../errors'
|
||||
import { UpsertFileInput, UpsertFileResponse } from '../gen/files/operations/upsertFile'
|
||||
|
||||
export type UploadFileInput = common.types.Simplify<
|
||||
Omit<UpsertFileInput, 'size'> & {
|
||||
content?: ArrayBuffer | Buffer | Blob | Uint8Array | string
|
||||
url?: string
|
||||
}
|
||||
>
|
||||
|
||||
export type UploadFileOutput = UpsertFileResponse
|
||||
|
||||
type UploadFileClient = {
|
||||
upsertFile: (input: UpsertFileInput) => Promise<UpsertFileResponse>
|
||||
}
|
||||
|
||||
export const upload = async (
|
||||
client: UploadFileClient,
|
||||
{
|
||||
key,
|
||||
index,
|
||||
tags,
|
||||
contentType,
|
||||
accessPolicies,
|
||||
content,
|
||||
url,
|
||||
indexing,
|
||||
expiresAt,
|
||||
metadata,
|
||||
publicContentImmediatelyAccessible,
|
||||
}: UploadFileInput
|
||||
): Promise<UploadFileOutput> => {
|
||||
if (url && content) {
|
||||
throw new errors.UploadFileError('Cannot provide both content and URL, please provide only one of them')
|
||||
}
|
||||
|
||||
if (url) {
|
||||
content = await axios
|
||||
.get(url, { responseType: 'arraybuffer' })
|
||||
.then((res) => res.data)
|
||||
.catch((err) => {
|
||||
throw new errors.UploadFileError(`Failed to download file from provided URL: ${err.message}`, err)
|
||||
})
|
||||
}
|
||||
|
||||
if (!content) {
|
||||
throw new errors.UploadFileError('No content was provided for the file')
|
||||
}
|
||||
|
||||
let buffer: ArrayBuffer | Buffer | Blob | Uint8Array
|
||||
let size: number
|
||||
|
||||
if (typeof content === 'string') {
|
||||
const encoder = new TextEncoder()
|
||||
const uint8Array = encoder.encode(content)
|
||||
// Uint8Array is supported by both Node.js and browsers. Buffer.from() is easier but Buffer is only available in Node.js.
|
||||
buffer = uint8Array
|
||||
size = uint8Array.byteLength
|
||||
} else if (content instanceof Uint8Array) {
|
||||
// This supports Buffer too as it's a subclass of Uint8Array
|
||||
buffer = content
|
||||
size = buffer.byteLength
|
||||
} else if (content instanceof ArrayBuffer) {
|
||||
buffer = content
|
||||
size = buffer.byteLength
|
||||
} else if (content instanceof Blob) {
|
||||
buffer = content
|
||||
size = content.size
|
||||
} else {
|
||||
throw new errors.UploadFileError('The provided content is not supported')
|
||||
}
|
||||
|
||||
const { file } = await client.upsertFile({
|
||||
key,
|
||||
tags,
|
||||
index,
|
||||
accessPolicies,
|
||||
contentType,
|
||||
metadata,
|
||||
size,
|
||||
expiresAt,
|
||||
indexing,
|
||||
publicContentImmediatelyAccessible,
|
||||
})
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': file.contentType,
|
||||
}
|
||||
|
||||
if (publicContentImmediatelyAccessible) {
|
||||
headers['x-amz-tagging'] = 'public=true'
|
||||
}
|
||||
|
||||
try {
|
||||
await axios.put(file.uploadUrl, buffer, {
|
||||
maxBodyLength: Infinity,
|
||||
headers,
|
||||
})
|
||||
} catch (thrown: unknown) {
|
||||
const err = thrown instanceof Error ? thrown : new Error(String(thrown))
|
||||
throw new errors.UploadFileError(`Failed to upload file: ${err.message}`, err as AxiosError, file)
|
||||
}
|
||||
|
||||
return {
|
||||
file: {
|
||||
...file,
|
||||
size,
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user