Skip to content

Commit a35f0e2

Browse files
committed
fix: multipart testing
1 parent 4c2379a commit a35f0e2

32 files changed

+1175
-1041
lines changed

docs/examples/functions/create-deployment.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const functions = new Functions(client);
99

1010
const response = await functions.createDeployment(
1111
'<FUNCTION_ID>', // functionId
12-
InputFile.fromPath('/path/to/file.png', 'file.png'), // code
12+
Payload.fromFile('/path/to/file.png'), // code
1313
false, // activate
1414
'<ENTRYPOINT>', // entrypoint (optional)
1515
'<COMMANDS>' // commands (optional)

docs/examples/functions/create-execution.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const functions = new Functions(client);
99

1010
const response = await functions.createExecution(
1111
'<FUNCTION_ID>', // functionId
12-
'<BODY>', // body (optional)
12+
Payload.fromJson({ x: "y" }), // body (optional)
1313
false, // async (optional)
1414
'<PATH>', // path (optional)
1515
ExecutionMethod.GET, // method (optional)

docs/examples/storage/create-file.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ const storage = new Storage(client);
1010
const response = await storage.createFile(
1111
'<BUCKET_ID>', // bucketId
1212
'<FILE_ID>', // fileId
13-
InputFile.fromPath('/path/to/file.png', 'file.png'), // file
13+
Payload.fromFile('/path/to/file.png'), // file
1414
["read("any")"] // permissions (optional)
1515
);

mod.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Query } from "./src/query.ts";
33
import { Permission } from "./src/permission.ts";
44
import { Role } from "./src/role.ts";
55
import { ID } from "./src/id.ts";
6-
import { InputFile } from "./src/inputFile.ts";
6+
import { Payload } from "./src/payload.ts";
77
import { AppwriteException } from "./src/exception.ts";
88
import { Account } from "./src/services/account.ts";
99
import { Avatars } from "./src/services/avatars.ts";
@@ -41,7 +41,7 @@ export {
4141
Permission,
4242
Role,
4343
ID,
44-
InputFile,
44+
Payload,
4545
AppwriteException,
4646
Account,
4747
Avatars,

src/client.ts

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { AppwriteException } from './exception.ts';
2+
import { Payload } from './payload.ts';
3+
import { getBoundary, parse as parseMultipart } from './multipart.ts';
24

3-
export interface Payload {
5+
export interface Params {
46
[key: string]: any;
57
}
68

@@ -9,13 +11,13 @@ export class Client {
911
static DENO_READ_CHUNK_SIZE = 16384; // 16kb; refference: https://github.com/denoland/deno/discussions/9906
1012

1113
endpoint: string = 'https://cloud.appwrite.io/v1';
12-
headers: Payload = {
14+
headers: Params = {
1315
'content-type': '',
14-
'user-agent' : `AppwriteDenoSDK/12.1.0 (${Deno.build.os}; ${Deno.build.arch})`,
16+
'user-agent' : `AppwriteDenoSDK/13.0.0 (${Deno.build.os}; ${Deno.build.arch})`,
1517
'x-sdk-name': 'Deno',
1618
'x-sdk-platform': 'server',
1719
'x-sdk-language': 'deno',
18-
'x-sdk-version': '12.1.0',
20+
'x-sdk-version': '13.0.0',
1921
'X-Appwrite-Response-Format':'1.6.0',
2022
};
2123

@@ -128,7 +130,7 @@ export class Client {
128130
return this;
129131
}
130132

131-
async call(method: string, path: string = "", headers: Payload = {}, params: Payload = {}, responseType: string = "json") {
133+
async call(method: string, path: string = "", headers: Params = {}, params: Params = {}, responseType: string = "json") {
132134
headers = {...this.headers, ...headers};
133135
const url = new URL(this.endpoint + path);
134136

@@ -192,6 +194,40 @@ export class Client {
192194
return response.headers.get("location");
193195
}
194196

197+
if (response.headers.get('content-type')?.includes('multipart/form-data')) {
198+
const boundary = getBoundary(
199+
response.headers.get("content-type") || ""
200+
);
201+
202+
const body = new Uint8Array(await response.arrayBuffer());
203+
const parts = parseMultipart(body, boundary);
204+
const partsObject: { [key: string]: any } = {};
205+
206+
for (const part of parts) {
207+
if (!part.name) {
208+
continue;
209+
}
210+
if (part.name === "responseBody") {
211+
partsObject[part.name] = Payload.fromBinary(part.data, part.filename);
212+
} else if (part.name === "responseStatusCode") {
213+
partsObject[part.name] = parseInt(part.data.toString());
214+
} else if (part.name === "duration") {
215+
partsObject[part.name] = parseFloat(part.data.toString());
216+
} else if (part.type === 'application/json') {
217+
try {
218+
partsObject[part.name] = JSON.parse(part.data.toString());
219+
} catch (e) {
220+
throw new Error(`Error parsing JSON for part ${part.name}: ${e instanceof Error ? e.message : 'Unknown error'}`);
221+
}
222+
} else {
223+
partsObject[part.name] = new TextDecoder().decode(part.data);
224+
}
225+
}
226+
227+
const data = partsObject;
228+
return data;
229+
}
230+
195231
const text = await response.text();
196232
let json = undefined;
197233
try {
@@ -202,8 +238,8 @@ export class Client {
202238
return json;
203239
}
204240

205-
static flatten(data: Payload, prefix = ''): Payload {
206-
let output: Payload = {};
241+
static flatten(data: Params, prefix = ''): Params {
242+
let output: Params = {};
207243

208244
for (const [key, value] of Object.entries(data)) {
209245
let finalKey = prefix ? prefix + '[' + key +']' : key;

src/enums/runtime.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ export enum Runtime {
1919
Python311 = 'python-3.11',
2020
Python312 = 'python-3.12',
2121
PythonMl311 = 'python-ml-3.11',
22+
Deno121 = 'deno-1.21',
23+
Deno124 = 'deno-1.24',
24+
Deno135 = 'deno-1.35',
2225
Deno140 = 'deno-1.40',
2326
Dart215 = 'dart-2.15',
2427
Dart216 = 'dart-2.16',

src/inputFile.ts

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/models.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Payload } from './payload.ts';
2+
13
export namespace Models {
24
/**
35
* Documents List
@@ -1917,7 +1919,7 @@ export namespace Models {
19171919
/**
19181920
* HTTP response body. This will return empty unless execution is created as synchronous.
19191921
*/
1920-
responseBody: string;
1922+
responseBody: Payload;
19211923
/**
19221924
* HTTP response headers as a key-value object. This will return only whitelisted headers. All headers are returned if execution is created as synchronous.
19231925
*/

0 commit comments

Comments
 (0)