1
0
mirror of https://github.com/sasjs/adapter.git synced 2025-12-11 01:14:36 +00:00

fix: viya updateFileContent not sending proper content-type

This commit is contained in:
2025-06-04 17:29:38 +02:00
parent b1c0e26c23
commit 49fba07824
3 changed files with 66 additions and 22 deletions

View File

@@ -29,6 +29,7 @@ import { executeOnComputeApi } from './api/viya/executeOnComputeApi'
import { getAccessTokenForViya } from './auth/getAccessTokenForViya' import { getAccessTokenForViya } from './auth/getAccessTokenForViya'
import { refreshTokensForViya } from './auth/refreshTokensForViya' import { refreshTokensForViya } from './auth/refreshTokensForViya'
import { FileContentUpdate } from './types/FileContentUpdate' import { FileContentUpdate } from './types/FileContentUpdate'
import { FileResource } from './types/FileResource'
interface JobExecutionResult { interface JobExecutionResult {
result?: { result: object } result?: { result: object }
@@ -324,7 +325,7 @@ export class SASViyaApiClient {
fileName: string, fileName: string,
accessToken?: string accessToken?: string
) { ) {
const { fileUri } = await this.getFileUri( const fileUri = await this.getFileUri(
folderPath, folderPath,
fileName, fileName,
accessToken accessToken
@@ -354,7 +355,7 @@ export class SASViyaApiClient {
content: string, content: string,
accessToken?: string accessToken?: string
) { ) {
const { fileUri, etag } = await this.getFileUri( const fileUri = await this.getFileUri(
folderPath, folderPath,
fileName, fileName,
accessToken accessToken
@@ -365,6 +366,18 @@ export class SASViyaApiClient {
) )
}) })
// Fetch the file resource details to get the Etag and content type
const { result: originalFileResource, etag } =
await this.requestClient.get<FileResource>(
`${this.serverUrl}${fileUri}`,
accessToken
)
if (!originalFileResource || !etag)
throw new Error(
`File ${fileName} does not have an ETag, or request failed.`
)
return await this.requestClient return await this.requestClient
.put<FileContentUpdate>( .put<FileContentUpdate>(
`${this.serverUrl}${fileUri}/content`, `${this.serverUrl}${fileUri}/content`,
@@ -372,7 +385,7 @@ export class SASViyaApiClient {
accessToken, accessToken,
{ {
'If-Match': etag, 'If-Match': etag,
'Content-Type': 'text/plain' 'Content-Type': originalFileResource.contentType
} }
) )
.then((res) => res.result) .then((res) => res.result)
@@ -1024,10 +1037,7 @@ export class SASViyaApiClient {
folderPath: string, folderPath: string,
fileName: string, fileName: string,
accessToken?: string accessToken?: string
): Promise<{ ): Promise<string> {
fileUri: string
etag: string
}> {
const folderMembers = await this.listFolder(folderPath, accessToken, 1000, { const folderMembers = await this.listFolder(folderPath, accessToken, 1000, {
returnDetails: true returnDetails: true
}).catch((err) => { }).catch((err) => {
@@ -1044,21 +1054,7 @@ export class SASViyaApiClient {
if (!fileUri) if (!fileUri)
throw new Error(`File ${fileName} not found in folder: ${folderPath}`) throw new Error(`File ${fileName} not found in folder: ${folderPath}`)
// Fetch the file details to get the resource ETag return fileUri
const { etag } = await this.requestClient.get<File>(
`${this.serverUrl}${fileUri}`,
accessToken
)
if (!etag)
throw new Error(
`File ${fileName} does not have an ETag, or request failed.`
)
return {
fileUri,
etag: etag || ''
}
} }
private async getRecycleBinUri(accessToken?: string) { private async getRecycleBinUri(accessToken?: string) {

View File

@@ -411,6 +411,13 @@ export default class SASjs {
) )
} }
/**
* Fetches the file content for a file in the specified folder.
*
* @param folderPath - the full path to the folder containing the file. eg: /Public/folder1/folder2
* @param fileName - the name of the file in the `folderPath`
* @param accessToken - an access token for authorizing the request
*/
public async getFileContent( public async getFileContent(
folderPath: string, folderPath: string,
fileName: string, fileName: string,
@@ -425,6 +432,14 @@ export default class SASjs {
) )
} }
/**
* Updates the file content for a file in the specified folder.
*
* @param folderPath - the full path to the folder containing the file. eg: /Public/folder1/folder2
* @param fileName - the name of the file in the `folderPath`
* @param content - the new content to be written to the file
* @param accessToken - an access token for authorizing the request
*/
public async updateFileContent( public async updateFileContent(
folderPath: string, folderPath: string,
fileName: string, fileName: string,

33
src/types/FileResource.ts Normal file
View File

@@ -0,0 +1,33 @@
export interface FileResource {
creationTimeStamp: string
modifiedTimeStamp: string
createdBy: string
modifiedBy: string
id: string
properties: Properties
contentDisposition: string
contentType: string
encoding: string
links: Link[]
name: string
size: number
searchable: boolean
fileStatus: string
fileVersion: number
typeDefName: string
version: number
virusDetected: boolean
urlDetected: boolean
quarantine: boolean
}
export interface Link {
method: string
rel: string
href: string
uri: string
type?: string
responseType?: string
}
export interface Properties {}